426 Stimmen

SQL Server - Rückgabewert nach INSERT

Ich versuche, einen Schlüsselwert nach einer INSERT-Anweisung zurückzubekommen. Beispiel: Ich habe eine Tabelle mit den Attributen name und id. id ist ein generierter Wert.

    INSERT INTO table (name) VALUES('bob');

Jetzt möchte ich die ID im selben Schritt zurückerhalten. Wie wird das gemacht?

Wir verwenden Microsoft SQL Server 2008.

636voto

gbn Punkte 407102

Keine Notwendigkeit für ein separates SELECT...

INSERT INTO table (name)
OUTPUT Inserted.ID
VALUES('bob');

Dies funktioniert auch für Nicht-IDENTITY-Spalten (wie GUIDs)

257voto

Curtis Punkte 98065

Utilice SCOPE_IDENTITY() um den neuen ID-Wert zu erhalten

INSERT INTO table (name) VALUES('bob');

SELECT SCOPE_IDENTITY()

http://msdn.microsoft.com/en-us/library/ms190315.aspx

57voto

hajikelist Punkte 1090
INSERT INTO files (title) VALUES ('whatever'); 
SELECT * FROM files WHERE id = SCOPE_IDENTITY();

Ist die sicherste Wette, da es ein bekanntes Problem mit OUTPUT-Klausel Konflikt auf Tabellen mit Triggern ist. Das macht dies ziemlich unzuverlässig, denn selbst wenn Ihre Tabelle derzeit keine Trigger hat, kann jemand, der später einen hinzufügt, Ihre Anwendung zerstören. Ein Verhalten wie eine Zeitbombe.

Siehe msdn-Artikel für eine genauere Erklärung:

http://blogs.msdn.com/b/sqlprogrammability/archive/2008/07/11/update-with-output-clause-triggers-and-sqlmoreresults.aspx

40voto

Ian Boyd Punkte 232380

Entity Framework führt etwas Ähnliches aus wie die Antwort von gbn:

DECLARE @generated_keys table([Id] uniqueidentifier)

INSERT INTO Customers(FirstName)
OUTPUT inserted.CustomerID INTO @generated_keys
VALUES('bob');

SELECT t.[CustomerID]
FROM @generated_keys AS g 
   JOIN dbo.Customers AS t 
   ON g.Id = t.CustomerID
WHERE @@ROWCOUNT > 0

Die Ausgabeergebnisse werden in einer temporären Tabellenvariablen gespeichert und dann an den Client zurückgegeben. Sie müssen sich des Problems bewusst sein:

Einfügungen können mehr als eine Zeile erzeugen, so dass die Variable mehr als eine Zeile enthalten kann, so dass Sie mehr als eine Zeile zurückerhalten können ID

Ich habe keine Ahnung, warum EF die ephemere Tabelle innerlich mit der echten Tabelle verbinden sollte (unter welchen Umständen sollten die beiden nicht übereinstimmen).

Aber das ist es, was EF tut.

Nur SQL Server 2008 oder neuere Versionen. Wenn er 2005 ist, haben Sie Pech.

24voto

Reza Jenabi Punkte 3356

Es gibt viele Möglichkeiten, nach dem Einfügen auszusteigen

Wenn Sie Daten in eine Tabelle einfügen, können Sie eine Kopie der Daten zurückgeben, die in die Tabelle eingefügt wurden. Die OUTPUT-Klausel hat zwei grundlegende Formen: OUTPUT und OUTPUT INTO. Verwenden Sie die OUTPUT-Form, wenn Sie die Daten an die aufrufende Anwendung zurückgeben wollen. Verwenden Sie die Form OUTPUT INTO, wenn Sie die Daten an eine Tabelle oder eine Tabellenvariable zurückgeben wollen.

DECLARE @MyTableVar TABLE (id INT,NAME NVARCHAR(50));

INSERT INTO tableName
(
  NAME,....
)OUTPUT INSERTED.id,INSERTED.Name INTO @MyTableVar
VALUES
(
   'test',...
)

IDENT_CURRENT : Sie gibt die letzte Identität zurück, die für eine bestimmte Tabelle oder Ansicht in einer beliebigen Sitzung erstellt wurde.

SELECT IDENT_CURRENT('tableName') AS [IDENT_CURRENT]

SCOPE_IDENTITÄT : Sie gibt die letzte Identität aus derselben Sitzung und demselben Bereich zurück. Ein Bereich ist eine gespeicherte Prozedur/Trigger usw.

SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY];  

@@IDENTITÄT : Sie gibt die letzte Identität aus derselben Sitzung zurück.

SELECT @@IDENTITY AS [@@IDENTITY];

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