Viele Leute werden Ihnen vorschlagen, MERGE
zu verwenden , aber ich warne davor. Standardmäßig schützt es Sie nicht mehr vor Nebenläufigkeit und Racebedingungen als mehrere Anweisungen, aber es bringt andere Gefahren mit sich:
- Seien Sie vorsichtig mit der MERGE-Anweisung von SQL Server
- Was Sie vermeiden sollten, wenn Sie MERGE verwenden möchten
- SQL Server UPSERT-Muster und Antimuster
Selbst mit dieser "einfacheren" Syntax bevorzuge ich immer noch diesen Ansatz (die Fehlerbehandlung wurde der Kürze halber weggelassen):
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
UPDATE dbo.table SET ... WHERE PK = @PK;
IF @@ROWCOUNT = 0
BEGIN
INSERT dbo.table(PK, ...) SELECT @PK, ...;
END
COMMIT TRANSACTION;
Weitere Informationen zu diesem UPSERT
Ansatz hier:
- Bitte hören Sie auf, dieses UPSERT-Anti-Pattern zu verwenden
Viele Leute werden diesen Weg vorschlagen:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
IF EXISTS (SELECT 1 FROM dbo.table WHERE PK = @PK)
BEGIN
UPDATE ...
END
ELSE
BEGIN
INSERT ...
END
COMMIT TRANSACTION;
Aber all dies stellt sicher, dass Sie die Tabelle möglicherweise zweimal lesen müssen, um die zu aktualisierende(n) Zeile(n) zu finden. Im ersten Beispiel müssen Sie die Zeile(n) immer nur einmal suchen. (In beiden Fällen erfolgt eine Einfügung, wenn beim anfänglichen Lesen keine Zeilen gefunden werden.)
Andere werden diesen Weg vorschlagen:
BEGIN TRY
INSERT ...
END TRY
BEGIN CATCH
IF ERROR_NUMBER() = 2627
UPDATE ...
END CATCH
Dies ist jedoch problematisch, wenn es aus keinem anderen Grund viel teurer ist, SQL Server Ausnahmen abfangen zu lassen, die Sie von vornherein hätten verhindern können, außer in dem seltenen Szenario, in dem fast jede Einfügung fehlschlägt. Das beweise ich hier:
- Überprüfen auf potenzielle Beschränkungsverletzungen vor der Eingabe von TRY/CATCH
- Auswirkung verschiedener Fehlerbehandlungstechniken auf die Leistung
Sie sind sich nicht sicher, was Sie Ihrer Meinung nach gewinnen, wenn Sie eine einzige Aussage haben; Ich glaube nicht, dass du etwas gewinnst. MERGE
ist eine einzelne Anweisung, muss aber trotzdem mehrere Operationen ausführen - auch wenn Sie denken, dass dies nicht der Fall ist.