如何使用INSERT语句的OUTPUT子句获取标识值?


240

如果我有一个插入语句,例如:

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

如何使用OUTPUT子句设置@var INT新行的标识值(称为Id)?我已经看到了将INSERTED.Name放入表变量的示例,但是我无法将其放入非表变量中。

我已经尝试了OUPUT INSERTED.Id AS @varSET @var = INSERTED.Id但是都没有用。


3
我已经知道@@ SCOPE_IDENTITY,我特别想知道如何使用OUPUT做到这一点。谢谢。
Yatrix 2012年

6
您需要将其插入表变量中,然后从中选择。没有从OUTPUT子句直接分配给标量变量的语法。
Martin Smith

3
OUTPUT子句具有以输出到一个表或表可变..
mellamokb

5
OUTPUT子句写入表。它可以是表变量,临时表...。
HABO 2012年

2
我的问题专门要求 OUTPUT子句。
Yatrix

Answers:


464

您可以像这样将新插入的ID输出到SSMS控制台:

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

当您需要将ID返回给调用应用程序时,也可以在C#中使用它,只需使用.ExecuteScalar()(而不是.ExecuteNonQuery())执行SQL查询以读取ID返回的结果即可。

或者,如果您需要捕获新插入的IDT-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在此处使用“常规”临时表()或什至“真实”持久表作为“输出目标”。


2
对于背后的代码,这里的答案很简洁。ExecuteScalar()FTW
Joe Johnston

10
您可以将结果插入real persistent table-中,这非常棒,因为这意味着您可以同时INSERTTWO表中提供信息。
gotqn 2015年

7
永远不要使用@@ IDENTITY从顶部拉出。提供了使用触发器的艰苦方法,因为它们记录了对一个表所做的更改历史记录,并且同时将它们插入到新表中,因此@@ IDENTITY开始从历史记录表中返回值。随之而来的是欢闹!请使用marc_s的解决方案。暂时我一直使用@OutputTbl方法,但是其他选项让我很感兴趣。
埃里克·比斯哈德

4
除了“ OUTPUT INTO子句的目标表不能位于(主键,外键)关系的任一侧”之外,OUTPUT INTO极为出色,对我而言,这大约占潜在用例的99%。我认为这是因为OUTPUT子句即使在事务回滚时也可以返回数据,但是有点烦人,很难一口气将数据插入相关表A和B中。
罗伯特·卡尔洪

3
@EricBishard对此SCOPE_IDENTITY()更好。
Derreck Dean
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.