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.

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 

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

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 
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.