SQL Server Output Clause na zmienną skalarną

134

Czy istnieje „prosty” sposób, aby to zrobić, czy też muszę przekazać zmienną tabeli o składni „OUTPUT ... INTO”?

DECLARE @someInt int

INSERT INTO MyTable2(AIntColumn)
OUTPUT @SomeInt = Inserted.AIntColumn
VALUES(12)
Benoittr
źródło

Odpowiedzi:

162

Potrzebujesz zmiennej tabeli i może to być takie proste.

declare @ID table (ID int)

insert into MyTable2(ID)
output inserted.ID into @ID
values (1)
Mikael Eriksson
źródło
47
Ale wtedy musiałbym „SELECT @someInt = ID FROM @ID”. Chciałem wiedzieć, czy można pominąć ten dodatkowy krok (i zmienną tabeli pośredniej), jeśli wszystko, czego potrzebuję, to wynikowa wartość int.
Benoittr,
@Benoittr - To zależy od tego, jak zamierzasz użyć wartości, może to nie być konieczne, możesz użyć tabeli w klauzuli from instrukcji select. Kiedy przypisujesz zmienną, musisz mieć również pewność, że insert wstawia tylko jeden wiersz. A jeśli insert wstawia tylko jeden wiersz, być może łatwiej jest uzyskać bezpośrednio to, co jest użyte w klauzuli wartości, zamiast używać output?
Mikael Eriksson
4
W przypadku wartości generowanej automatycznie nie zawsze jest możliwe wcześniejsze poznanie wartości (tożsamość, kolumny wyliczane). Rozumiem, że istnieje wiele obejść. Mimo to dałeś mi odpowiedź, której szukałem. Dzięki
Benoittr,
1
Potrzebujesz tego w zwykłej zmiennej? 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
32

Ponad rok później ... jeśli potrzebujesz automatycznie wygenerowanego identyfikatora tabeli, możesz po prostu

SELECT @ReportOptionId = SCOPE_IDENTITY()

W przeciwnym razie wydaje się, że utknąłeś z używaniem stołu.

Alejandro B.
źródło
6
Zmienna, której szukałem, była naprawdę czymś innym niż kolumna tożsamości. Mimo to dziękuję za odpowiedź.
Benoittr
27
Najwyraźniej ma to problemy w planie wieloprocesorowym równoległym, a OUTPUT jest jedyną zawsze godną zaufania metodą.
andrewb
6
SCOPE_IDENTITY () może zwrócić coś, nawet jeśli ostatnia INSERT niczego nie wstawiła, prawda? To sprawi, że w niektórych przypadkach będzie bezużyteczny.
Patrick Honorez
2
lepiej użyć klauzuli wyjściowej
Clay Smith
1
Błąd, do którego odnosi się @andrewb, został naprawiony w 2008 R2 z dodatkiem SP1 .
adam0101
6

Później, ale nadal warto wspomnieć, że można również używać zmiennych do wyprowadzania wartości w klauzuli SET polecenia UPDATE lub w polach SELECT;

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

W powyższym przykładzie @ val1 ma wartość przed, a @ val2 ma wartość końcową, chociaż podejrzewam, że jakiekolwiek zmiany z wyzwalacza nie byłyby w val2, więc w takim przypadku musiałbyś przejść z tabelą wyjściową. W każdym przypadku poza najprostszym, myślę, że tabela wyjściowa będzie również bardziej czytelna w twoim kodzie.

Jest to bardzo pomocne, gdy chcesz zamienić kolumnę na listę oddzieloną przecinkami;

DECLARE @list varchar(max) = '';
DECLARE @comma varchar(2) = '';
SELECT @list = @list + @comma + County, @comma = ', ' FROM County
print @list
Jay13
źródło
Dzięki! To była informacja, której potrzebowałem
Wizou,
1
ŁAŁ! Nie wiedziałem, że potrafisz SET @val2 = NextNum = NextNum + 1.
Sam
Zupełnie inny niż to, o co pytano, w ogóle nie pomógł, ponieważ szukałem sposobu na przypisanie OUTPUTwartości zmiennej w INSERTklauzuli przy użyciu INSERT-OUTPUT-VALUESpodejścia zadanego przez pytającego.
Fawad Raza