Предложение вывода SQL Server в скалярную переменную

134

Есть ли какой-нибудь «простой» способ сделать это или мне нужно передать табличную переменную с синтаксисом «OUTPUT ... INTO»?

DECLARE @someInt int

INSERT INTO MyTable2(AIntColumn)
OUTPUT @SomeInt = Inserted.AIntColumn
VALUES(12)
Benoittr
источник

Ответы:

161

Вам нужна табличная переменная, и это может быть так просто.

declare @ID table (ID int)

insert into MyTable2(ID)
output inserted.ID into @ID
values (1)
Микаэль Эрикссон
источник
45
Но тогда мне пришлось бы «ВЫБРАТЬ @someInt = ID FROM @ID». Я хотел знать, можно ли пропустить этот дополнительный шаг (и промежуточную переменную таблицы), если все, что мне нужно, это результирующий int.
Benoittr
@Benoittr - Это зависит от того, как вы собираетесь использовать значение, это может быть необязательно, вы можете использовать таблицу в предложении from оператора select. Когда вы назначаете переменную, вы также должны быть уверены, что вставка вставила только одну строку. И если вставка вставила только одну строку, возможно, проще получить то, что используется в предложении значений напрямую, а не использовать output?
Микаэль Эрикссон
4
В случае автоматически сгенерированного значения не всегда возможно узнать значения заранее (идентичность, вычисляемые столбцы). Я понимаю, что есть много обходных путей. Тем не менее, вы дали мне ответ, который я искал. Спасибо
Benoittr
Нужна в обычной переменной? 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);
Арво Боуэн,
30

Более года спустя ... если вам нужно получить автоматически сгенерированный идентификатор таблицы, вы можете просто

SELECT @ReportOptionId = SCOPE_IDENTITY()

В противном случае кажется, что вы застряли в использовании таблицы.

Алехандро Б.
источник
6
Переменная, которую я искал, на самом деле была чем-то еще, чем столбец идентичности. Тем не менее, спасибо за ответ.
Benoittr
26
По-видимому, у этого есть проблемы в многопроцессорном параллельном плане, и OUTPUT - единственный всегда заслуживающий доверия метод.
andrewb
6
SCOPE_IDENTITY () может что-то вернуть, даже если последний INSERT ничего не вставил, верно? В некоторых случаях это сделало бы его непригодным для использования.
Патрик Онорез
2
лучше использовать предложение вывода
Клэй Смит
1
Ошибка, на которую ссылается @andrewb, исправлена ​​в 2008 R2 SP1 .
adam0101
6

Позже, но все же стоит упомянуть, что вы также можете использовать переменные для вывода значений в предложении SET UPDATE или в полях 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

В приведенном выше примере @ val1 имеет значение до, а @ val2 имеет значение после, хотя я подозреваю, что никаких изменений из триггера не будет в val2, поэтому в этом случае вам придется использовать выходную таблицу. В любом случае, кроме простейшего, я думаю, что и в вашем коде таблица вывода будет более читаемой.

Это очень полезно, если вы хотите превратить столбец в список, разделенный запятыми;

DECLARE @list varchar(max) = '';
DECLARE @comma varchar(2) = '';
SELECT @list = @list + @comma + County, @comma = ', ' FROM County
print @list
Jay13
источник
Спасибо! Это была та информация, которая мне была нужна
Wizou
1
ВОТ ЭТО ДА! Я не знал, что ты умеешь SET @val2 = NextNum = NextNum + 1.
Сэм
Полностью отличается от того, что было задано, совсем не помогло, потому что я искал способ присвоить OUTPUTзначение переменной в INSERTпредложении, используя INSERT-OUTPUT-VALUESподход, который просил спрашивающий.
Fwd079