Ich versuche, den 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 in demselben Schritt zurückholen. Wie wird das gemacht?
Wir verwenden Microsoft SQL Server 2008.
Kein separates SELECT erforderlich ...
INSERT INTO table (name)
OUTPUT Inserted.ID
VALUES('bob');
Dies funktioniert auch für Nicht-IDENTITY-Spalten (z. B. GUIDs)
Verwenden Sie SCOPE_IDENTITY()
, um den neuen ID-Wert abzurufen
INSERT INTO table (name) VALUES('bob');
SELECT SCOPE_IDENTITY()
INSERT INTO files (title) VALUES ('whatever');
SELECT * FROM files WHERE id = SCOPE_IDENTITY();
Ist die sicherste Wette, da ein Problem mit dem OUTPUT-Klauselkonflikt an Tabellen mit Auslösern bekannt ist. Dies macht es ziemlich unzuverlässig, auch wenn Ihre Tabelle derzeit keine Auslöser hat - jemand, der einen in der Zeile hinzufügt, wird Ihre Anwendung beschädigen. Time Bomb Art Verhalten.
Eine ausführlichere Erklärung finden Sie im msdn-Artikel:
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. Muss sich der Gotcha bewusst sein:
einfügungen können mehr als eine Zeile generieren, sodass die Variable mehr als eine Zeile enthalten kann, sodass Sie mehr als eine
ID
zurückgeben können.
Ich habe keine Ahnung, warum EF die ephemere Tabelle wieder mit der realen Tabelle verbinden würde (unter welchen Umständen würden die beiden nicht übereinstimmen).
Aber genau das macht EF.
Nur SQL Server 2008 oder neuer. Wenn es 2005 ist, haben Sie kein Glück.
IDENTITY Ist eine Systemfunktion, die den zuletzt eingegebenen Identitätswert zurückgibt.
Mit scope_identity können Sie die ID der Zeile auswählen, die Sie gerade in eine Variable eingefügt haben. Wählen Sie dann einfach die gewünschten Spalten aus dieser Tabelle aus, wobei id = die Identität ist, die Sie von scope_identity erhalten haben
Hier finden Sie die MSDN-Informationen http://msdn.Microsoft.com/en-us/library/ms190315.aspx
die beste und sicherste Lösung ist die Verwendung von SCOPE_IDENTITY . Sie müssen nur nach jeder Einfügung die Bereichsidentität abrufen und sie in einer Variablen speichern, da Sie zwei Einfügungen in demselben Bereich aufrufen können. _ Identität und @ Identität Vielleicht funktionieren sie, aber sie sind nicht sicher. Sie können Probleme in einer großen Anwendung haben
declare @duplicataId int
select @duplicataId = (SELECT SCOPE_IDENTITY())
Weitere Details finden Sie hier Microsoft docs
Sie können eine Auswahlanweisung an Ihre Einfügeanweisung anhängen .. _. Integer myInt = Einfügen in Tabelle1 (FName) values ('Fred'); Wählen Sie Scope_Identity (); Dies gibt einen Wert der Identität zurück, wenn der Scaler ausgeführt wird.
So verwende ich OUTPUT INSERTED beim Einfügen in eine Tabelle, die ID als Identitätsspalte in SQL Server verwendet:
'myConn is the ADO connection, RS a recordset and ID an integer
Set RS=myConn.Execute("INSERT INTO M2_VOTELIST(PRODUCER_ID,TITLE,TIMEU) OUTPUT INSERTED.ID VALUES ('Gator','Test',GETDATE())")
ID=RS(0)