Как использовать предложение OUTPUT оператора INSERT, чтобы получить значение идентификатора?

240

Если у меня есть оператор вставки, такой как:

INSERT INTO MyTable
(  
  Name,
  Address,
  PhoneNo
)
VALUES
(
  'Yatrix',
   '1234 Address Stuff',
   '1112223333'
)

Как установить @var INTзначение идентификатора новой строки (вызывается Id) с помощью предложения OUTPUT? Например, я видел примеры размещения INSERTED.Name в табличных переменных, но я не могу получить его в не табличной переменной.

Я пытался OUPUT INSERTED.Id AS @var, SET @var = INSERTED.Idно ни один не работал.

Yatrix
источник
3
Я уже знаю о @@ SCOPE_IDENTITY, особенно хочу узнать, как это сделать с OUPUT. Спасибо.
Ятрикс
6
Вам нужно вставить ее в табличную переменную, а затем выбрать из нее. Нет синтаксиса для непосредственного присвоения скалярной переменной из OUTPUTпредложения.
Мартин Смит
3
Предложение OUTPUT должно выводиться в таблицу или табличную переменную ..
mellamokb
5
Предложение OUTPUTпишет в таблицу. Это может быть табличная переменная, временная таблица, ....
HABO
2
Мой вопрос специально просит предложение OUTPUT.
Ятрикс

Ответы:

464

Вы можете получить только что вставленный ID, выводимый на консоль SSMS следующим образом:

INSERT INTO MyTable(Name, Address, PhoneNo)
OUTPUT INSERTED.ID
VALUES ('Yatrix', '1234 Address Stuff', '1112223333')

Вы также можете использовать это, например, из C #, когда вам нужно вернуть идентификатор в вызывающее приложение - просто выполните SQL-запрос с .ExecuteScalar()(вместо .ExecuteNonQuery()), чтобы прочитать полученный результат ID.

Или, если вам нужно захватить недавно вставленный IDв T-SQL (например, для дальнейшей обработки), вам нужно создать переменную таблицы:

DECLARE @OutputTbl TABLE (ID INT)

INSERT INTO MyTable(Name, Address, PhoneNo)
OUTPUT INSERTED.ID INTO @OutputTbl(ID)
VALUES ('Yatrix', '1234 Address Stuff', '1112223333')

Таким образом, вы можете поместить в них несколько значений @OutputTblи выполнить их дальнейшую обработку. Вы также можете использовать «обычную» временную таблицу ( #temp) или даже «настоящую» постоянную таблицу в качестве «выходной цели» здесь.

marc_s
источник
2
Ответ здесь для кода был кратким. ExecuteScalar () FTW
Джо Джонстон
10
Вы можете вставить результат в real persistent table- это невероятно, потому что это означает, что вы можете одновременно INSERTполучать информацию в TWOтаблицах.
получил
7
Никогда не используйте @@ IDENTITY, чтобы тянуть сверху. Вычеркните трудный путь работы с триггерами, и, поскольку они записывали историю изменений, внесенных в одну таблицу, и одновременно вставляли их в новую таблицу, @@ IDENTITY начал возвращать обратно значения из таблицы истории. оттуда вытекает веселье! Пожалуйста, используйте решение marc_s. В настоящее время я использую метод @OutputTbl, но меня заинтриговали другие варианты.
Эрик Бишард
4
OUTPUT INTO чрезвычайно фантастичен, за исключением того, что «таблица назначения предложения OUTPUT INTO не может находиться ни по одной из сторон (первичный ключ, внешний ключ)», что для меня составляет около 99% потенциальных случаев использования. Я предполагаю, что это потому, что предложение OUTPUT может возвращать данные, даже когда транзакция откатывается, но это немного раздражает, так сложно вставить данные в связанные таблицы A и B за один раз.
Роберт Калхун
3
@EricBishard SCOPE_IDENTITY()работает лучше для этого.
Дерек Дин