SQL Server-Ausgabeklausel in eine skalare Variable

134

Gibt es eine "einfache" Möglichkeit, dies zu tun, oder muss ich eine Tabellenvariable mit der Syntax "OUTPUT ... INTO" übergeben?

DECLARE @someInt int

INSERT INTO MyTable2(AIntColumn)
OUTPUT @SomeInt = Inserted.AIntColumn
VALUES(12)
Benoittr
quelle

Antworten:

161

Sie benötigen eine Tabellenvariable und es kann so einfach sein.

declare @ID table (ID int)

insert into MyTable2(ID)
output inserted.ID into @ID
values (1)
Mikael Eriksson
quelle
45
Aber dann müsste ich "SELECT @someInt = ID FROM @ID". Ich wollte wissen, ob es möglich ist, diesen zusätzlichen Schritt (und die zwischengeschaltete Tabellenvariable) zu überspringen, wenn ich nur das resultierende int benötige.
Benoittr
@Benoittr - Das hängt davon ab, wie Sie den Wert verwenden. Möglicherweise ist dies nicht erforderlich. Sie können die Tabelle in einer from-Klausel einer select-Anweisung verwenden. Wenn Sie eine Variable zuweisen, müssen Sie auch sicherstellen, dass beim Einfügen nur eine Zeile eingefügt wurde. Und wenn die Einfügung nur eine Zeile eingefügt hat, ist es vielleicht einfacher, direkt zu erfassen, was in der Werteklausel verwendet wird, als zu verwenden output?
Mikael Eriksson
4
Bei automatisch generierten Werten ist es nicht immer möglich, die Werte im Voraus zu kennen (Identität, berechnete Spalten). Ich verstehe, dass es viele Problemumgehungen gibt. Trotzdem hast du mir die Antwort gegeben, nach der ich gesucht habe. Vielen Dank
Benoittr
Benötigen Sie es in einer regulären Variablen? DECLARE @InsertedIDResults TABLE (ID int); INSERT INTO MyTable (Name, Age) OUTPUT INSERTED.ID INTO @InsertedIDResults VALUES('My Name', 30); DECLARE @InsertedID int = (SELECT TOP 1 ID FROM @InsertedIDResults);
Arvo Bowen
30

Über ein Jahr später ... wenn Sie die automatisch generierte ID einer Tabelle benötigen, können Sie dies einfach tun

SELECT @ReportOptionId = SCOPE_IDENTITY()

Ansonsten scheint es, als ob Sie mit der Verwendung einer Tabelle nicht weiterkommen.

Alejandro B.
quelle
6
Die Variable, nach der ich wirklich gesucht habe, war etwas anderes als die Identitätsspalte. Trotzdem danke für die Antwort.
Benoittr
26
Anscheinend hat dies Probleme in einem Multi-Prozessor-Parallelplan, und OUTPUT ist die einzige immer vertrauenswürdige Methode.
Andrew
6
SCOPE_IDENTITY () könnte etwas zurückgeben, selbst wenn das letzte INSERT nichts eingefügt hat, oder? Das würde es in einigen Fällen unbrauchbar machen.
Patrick Honorez
2
besser zu verwenden Ausgabeklausel
Clay Smith
1
Der Fehler, auf den sich @andrewb bezieht, wurde in 2008 R2 SP1 behoben .
adam0101
6

Viel später, aber immer noch erwähnenswert, können Sie auch Variablen verwenden, um Werte in der SET-Klausel eines UPDATE oder in den Feldern eines SELECT auszugeben.

DECLARE @val1 int;
DECLARE @val2 int;
UPDATE [dbo].[PortalCounters_TEST]
SET @val1 = NextNum, @val2 = NextNum = NextNum + 1
WHERE [Condition] = 'unique value'
SELECT @val1, @val2

Im obigen Beispiel hat @ val1 den Vorher-Wert und @ val2 den Nachher-Wert, obwohl ich vermute, dass Änderungen von einem Trigger nicht in val2 enthalten sind, sodass Sie in diesem Fall mit der Ausgabetabelle arbeiten müssten. Für alles andere als den einfachsten Fall denke ich, dass die Ausgabetabelle auch in Ihrem Code besser lesbar ist.

Dies ist sehr hilfreich, wenn Sie eine Spalte in eine durch Kommas getrennte Liste umwandeln möchten.

DECLARE @list varchar(max) = '';
DECLARE @comma varchar(2) = '';
SELECT @list = @list + @comma + County, @comma = ', ' FROM County
print @list
Jay13
quelle
Vielen Dank! Dies war die Information, die ich brauchte
Wizou
1
BEEINDRUCKEND! Ich wusste nicht, dass du es kannst SET @val2 = NextNum = NextNum + 1.
Sam