738 Stimmen

Lösungen für INSERT OR UPDATE auf SQL Server

Nehmen wir eine Tabellenstruktur von MyTable(KEY, datafield1, datafield2...) .

Häufig möchte ich entweder einen vorhandenen Datensatz aktualisieren oder einen neuen Datensatz einfügen, wenn dieser noch nicht existiert.

Im Wesentlichen:

IF (key exists)
  run update command
ELSE
  run insert command

Wie kann man das am besten schreiben?

53 Stimmen

Für alle, die diese Frage zum ersten Mal stellen - bitte lesen Sie unbedingt alle Antworten und Kommentare. Das Alter kann manchmal zu irreführenden Informationen führen...

1 Stimmen

Erwägen Sie die Verwendung des EXCEPT-Operators, der in SQL Server 2005 eingeführt wurde.

1voto

Dev Punkte 71

Ich hatte unten Lösung versucht und es funktioniert für mich, wenn gleichzeitige Anforderung für Insert-Anweisung auftritt.

begin tran
if exists (select * from table with (updlock,serializable) where key = @key)
begin
   update table set ...
   where key = @key
end
else
begin
   insert table (key, ...)
   values (@key, ...)
end
commit tran

1voto

Eugene Kaurov Punkte 1780

MySQL (und später auch SQLite) unterstützen auch die REPLACE INTO-Syntax:

REPLACE INTO MyTable (KEY, datafield1, datafield2) VALUES (5, '123', 'overwrite');

Dadurch wird der Primärschlüssel automatisch identifiziert und eine passende Zeile für die Aktualisierung gefunden, wobei eine neue Zeile eingefügt wird, wenn keine gefunden wird.

Dokumentation: https://dev.mysql.com/doc/refman/8.0/en/replace.html

0voto

Nenad Punkte 22188

Unter der Annahme, dass Sie eine einzelne Zeile einfügen/aktualisieren möchten, ist der optimale Ansatz die Verwendung der SQL Server-Funktion REPEATABLE READ Isolationsebene der Transaktion:

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN TRANSACTION

    IF (EXISTS (SELECT * FROM myTable WHERE key=@key)
        UPDATE myTable SET ...
        WHERE key=@key
    ELSE
        INSERT INTO myTable (key, ...)
        VALUES (@key, ...)

COMMIT TRANSACTION

Diese Isolationsstufe wird nachfolgende wiederholte Lesetransaktionen verhindern/sperren vom Zugriff auf die gleiche Zeile ( WHERE key=@key ), während die laufende Transaktion geöffnet ist. Andererseits, Operationen in einer anderen Zeile werden nicht blockiert ( WHERE key=@key2 ).

-1voto

Bart Punkte 1111

In SQL Server 2008 können Sie die MERGE-Anweisung verwenden

12 Stimmen

Dies ist ein Kommentar. In Ermangelung eines konkreten Beispielcodes ist dies genau wie viele andere Kommentare auf dieser Website.

0 Stimmen

Sehr alt, aber ein Beispiel wäre schön.

-2voto

nruessmann Punkte 305

Wenn Sie ADO.NET verwenden, übernimmt dies der DataAdapter.

Wenn Sie die Sache selbst in die Hand nehmen wollen, ist dies der richtige Weg:

Vergewissern Sie sich, dass eine Primärschlüssel-Beschränkung für Ihre Schlüsselspalte besteht.

Dann Sie:

  1. Aktualisieren Sie
  2. Wenn die Aktualisierung fehlschlägt, weil bereits ein Datensatz mit dem Schlüssel existiert, fügen Sie ihn ein. Wenn die Aktualisierung nicht fehlschlägt, sind Sie fertig.

Sie können es auch andersherum machen, d.h. zuerst die Einfügung vornehmen und dann die Aktualisierung, wenn die Einfügung fehlschlägt. Normalerweise ist der erste Weg besser, da Aktualisierungen häufiger durchgeführt werden als Einfügungen.

0 Stimmen

...und die Einfügung zuerst zu machen (wissend, dass sie manchmal fehlschlägt) ist teuer für SQL Server. sqlperformance.com/2012/08/t-sql-abfragen/fehler-handhabung

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X