Wie verwende ich die OUTPUT-Klausel einer INSERT-Anweisung, um den Identitätswert abzurufen?

239

Wenn ich eine Einfügeanweisung habe wie:

INSERT INTO MyTable
(  
  Name,
  Address,
  PhoneNo
)
VALUES
(
  'Yatrix',
   '1234 Address Stuff',
   '1112223333'
)

Wie setze ich @var INTden Identitätswert der neuen Zeile (aufgerufen Id) mithilfe der OUTPUT-Klausel? Ich habe Beispiele gesehen, wie INSERTED.Name zum Beispiel in Tabellenvariablen eingefügt wurde, aber ich kann es nicht in eine Nicht-Tabellenvariable bringen.

Ich habe versucht OUPUT INSERTED.Id AS @var, SET @var = INSERTED.Idaber weder gearbeitet haben.

Yatrix
quelle
3
Ich kenne @@ SCOPE_IDENTITY bereits, ich möchte speziell wissen, wie es mit OUPUT geht. Vielen Dank.
Yatrix
6
Sie müssen es in eine Tabellenvariable einfügen und dann auswählen. Es gibt keine Syntax, die einer skalaren Variablen aus der OUTPUTKlausel direkt zugewiesen werden kann .
Martin Smith
3
Die OUTPUT-Klausel muss in eine Tabelle oder Tabellenvariable ausgegeben werden.
mellamokb
5
Die OUTPUTKlausel schreibt in eine Tabelle. Es kann eine Tabellenvariable, eine temporäre Tabelle, .... sein.
HABO
2
Meine Frage fragt speziell nach der OUTPUT-Klausel.
Yatrix

Antworten:

463

Sie können die neu eingefügte ID entweder wie folgt an die SSMS-Konsole ausgeben lassen:

INSERT INTO MyTable(Name, Address, PhoneNo)
OUTPUT INSERTED.ID
VALUES ('Yatrix', '1234 Address Stuff', '1112223333')

Sie können dies auch von z. B. C # aus verwenden, wenn Sie die ID zurück zu Ihrer aufrufenden App benötigen - führen Sie einfach die SQL-Abfrage mit .ExecuteScalar()(anstelle von aus.ExecuteNonQuery() ) aus, um das resultierende IDzurückzulesen.

Oder wenn Sie das neu eingefügte IDin T-SQL erfassen müssen (z. B. für die spätere weitere Verarbeitung), müssen Sie eine Tabellenvariable erstellen:

DECLARE @OutputTbl TABLE (ID INT)

INSERT INTO MyTable(Name, Address, PhoneNo)
OUTPUT INSERTED.ID INTO @OutputTbl(ID)
VALUES ('Yatrix', '1234 Address Stuff', '1112223333')

Auf diese Weise können Sie mehrere Werte eingeben @OutputTblund diese weiter verarbeiten. Sie können hier auch eine "normale" temporäre Tabelle ( #temp) oder sogar eine "echte" persistente Tabelle als "Ausgabeziel" verwenden.

marc_s
quelle
2
Die Antwort hier für den Code dahinter war kurz. ExecuteScalar () FTW
Joe Johnston
10
Sie können das Ergebnis in a einfügen real persistent table- dies ist äußerst fantastisch, da Sie gleichzeitig INSERTInformationen in TWOTabellen einfügen können .
Gotqn
7
Verwenden Sie niemals @@ IDENTITY, um von oben zu ziehen. Machen Sie sich die harte Arbeit mit Triggern zunutze und da sie den Verlauf von Änderungen an einer Tabelle aufzeichneten und gleichzeitig in eine neue Tabelle einfügten, begann @@ IDENTITY, Werte aus der Verlaufstabelle zurückzugeben. Heiterkeit entsteht von dort! Bitte verwenden Sie die Lösung von marc_s. Vorerst habe ich mich für die @ OutputTbl-Methode entschieden, bin aber von den anderen Optionen fasziniert.
Eric Bishard
4
OUTPUT INTO ist äußerst fantastisch, mit der Ausnahme, dass "die Zieltabelle der OUTPUT INTO-Klausel nicht auf beiden Seiten einer Beziehung (Primärschlüssel, Fremdschlüssel) stehen darf", was für mich etwa 99% der potenziellen Anwendungsfälle ausmacht. Ich gehe davon aus, dass dies daran liegt, dass die OUTPUT-Klausel Daten zurückgeben kann, selbst wenn die Transaktion zurückgesetzt wird, aber es ist ein wenig ärgerlich, dass es so schwierig ist, Daten auf einmal in verwandte Tabellen A und B einzufügen.
Robert Calhoun
3
@EricBishard SCOPE_IDENTITY()funktioniert dafür besser.
Derreck Dean