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

Eine Zeile nur einfügen, wenn sie noch nicht vorhanden ist

Was ist mit dem "JFDI"-Muster?

BEGIN TRY
   INSERT etc
END TRY
BEGIN CATCH
    IF ERROR_NUMBER() <> 2627
      RAISERROR etc
END CATCH

Im Ernst, das geht ohne Sperren am schnellsten und gleichzeitig am besten, insbesondere bei hohen Volumen. Was ist, wenn UPDLOCK eskaliert und die gesamte Tabelle gesperrt wird?

Lesen Sie Lektion 4:

Lektion 4: Als ich die Upsert-Prozedur vor dem Optimieren der Indizes entwickelte, vertraute ich zunächst darauf, dass If Exists(Select…) line würde für jedes Element ausgelöst und Duplikate verboten. Nada. In kurzer Zeit gab es Tausende von Duplikaten, da dasselbe Element in derselben Millisekunde auf den Upsert traf und beide Transaktionen ein „nicht vorhanden“ erkannten und die Einfügung durchführten. Nach vielen Tests bestand die Lösung darin, den eindeutigen Index zu verwenden, den Fehler abzufangen und erneut zu versuchen, der Transaktion zu erlauben, die Zeile zu sehen und statt einer Einfügung eine Aktualisierung durchzuführen.