UPDATE OUTPUT in eine Variable

70

Ich versuche, ein Update und eine Auswahl durchzuführen ... im Grunde genommen ein Update basierend auf einem Index und wähle dann die Zeilen-ID aus, die aktualisiert wurde.

Dies ist mit der OUTPUT-Klausel einfach:

UPDATE Foo
SET Bar = 1
OUTPUT INSERTED.Id
WHERE Baz = 2

Aber wie bekomme ich das in eine Variable?

DECLARE @id INT

Diese drei funktionieren nicht:

UPDATE Foo
SET Bar = 1
OUTPUT @id = INSERTED.Id
WHERE Baz = 2

SET @id =
(UPDATE Foo
 SET Bar = 1
 OUTPUT INSERTED.Id
 WHERE Baz = 2)

SET @id =
(SELECT Id FROM (UPDATE Foo
                 SET Bar = 1
                 OUTPUT INSERTED.Id Id
                 WHERE Baz = 2) z)

Das letzte schloss ein, weil es mich vorübergehend aufgeregt hatte, als alle roten Schnörkel im Management Studio verschwanden. Leider bekomme ich diesen Fehler:

A nested INSERT, UPDATE, DELETE, or MERGE statement is not allowed in a SELECT statement that is not the immediate source of rows for an INSERT statement.
Cory Nelson
quelle

Antworten:

92

Wenn nur eine Zeile betroffen ist, kann dies ohne eine Tabellenvariable erfolgen.

DECLARE @id INT

UPDATE Foo 
SET Bar = 1, @id = id 
WHERE Baz = 2

SELECT @id 
Arpit Jain
quelle
5
Daran habe ich noch nie gedacht. Sehr schön!
Cory Nelson
2
Danke Cory, ich habe mich gefragt, ob das Schlüsselwort set im Update eine Variable setzen kann und es hat funktioniert!
Arpit Jain
Funktioniert dies insertfür eine einzelne betroffene Zeile?
Rahoolm
Kein @rahoolm, nur die Schlüsselwörter SETund SELECTkönnen eine Variable ändern und diese Schlüsselwörter können nicht mit INSERTAnweisung verwendet werden
Arpit Jain
1
Diesem Ansatz sind einige Grenzen gesetzt. Wenn Sie beispielsweise eine Zeilenversionsspalte haben, wird die letzte Zeilenversion zurückgegeben, nicht die, die sich aus Ihrer Aktualisierung ergibt.
Benutzer1664043
94

Da ein Update mehrere Zeilen betreffen kann, muss eine Tabelle die Ergebnisse speichern:

declare @ids table (id int);

UPDATE Foo
SET Bar = 1
OUTPUT INSERTED.Id INTO @ids
WHERE Baz = 2

Wenn Sie sicher sind, dass nur eine Zeile betroffen ist, können Sie die ID wie folgt herausziehen:

declare @id int
select  top 1 @id = id
from    @ids
Andomar
quelle
1
Sie müssen keine Tabelle für die Ergebnisse haben. Sie können dies tun: OUPUT INSERTED. * Natürlich werden dadurch alle Spalten zurückgebracht.
Norbert Norbertson
6

Alternativ, wenn nur eine Zeile betroffen ist:

DECLARE @id INT

UPDATE Foo 
SET @id = Bar = 1  ---Yes, this is valid!
WHERE Baz = 2

SELECT @id 
Carl Nitzsche
quelle