Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

UPDATE, falls vorhanden, sonst INSERT in SQL Server 2008

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.