T-Sql @@Identity

5

有人知道在使用T-Sql时如何返回@@Identity吗?

类似于这样:

set @Sql = "insert into table....values()..."
exec @sql
return @@Identity

1
你是什么意思返回@@Identity?从哪里?你是否确实需要@@Identity或scope_identity? - Martin Smith
@user - 所以,如果原始表上的触发器插入到具有标识列的另一个表中,您需要该第二个表的标识列吗? - Martin Smith
6
@user,Martin 的意思是有几种方法可以返回标识值(如 @@Identity、Scope_Identity() 函数等),这些方案的出现是因为在使用最古老的 @@Identity 时存在问题。你应该(除非你已经知道这点)了解这些方法,并确保 @@Identity 真的是最适合你的应用程序的方法。 - Charles Bretana
如果您发布代码或XML,请在文本编辑器中突出显示这些行,并单击编辑器工具栏上的“代码”按钮(101 010)以使其格式化和语法高亮! - marc_s
在任何情况下,我都不会使用@@identity来完成此操作。这样做最终会导致数据完整性问题,因为有些情况下@@identity会返回错误的值。应该使用output子句或scope_identity。 - HLGEM
5个回答

6

看起来你的一个隐含需求是执行动态SQL。虽然我建议不要这样做,但你可以通过以下方法实现你想要的效果:

set @Sql = 'insert into table....values()...; select SCOPE_IDENTITY()'
exec(@Sql)

4

像这样:

INSERT INTO Table(...)
OUTPUT INSERTED.IdColumn
VALUES(...)

这将适用于2008年及以上版本。而且它的美妙之处在于,如果需要,您还可以返回其他字段。 - HLGEM

3
在您的插入语句后添加“;select @@identity”:
insert into tab (x,y,z) values (a,b,c); select @@identity

返回的值是ID(使用ExecuteScalar)。

1
请注意,如果您有一个插入触发器将行插入到另一个具有标识列的表中,则使用@@identity将产生不正确的结果。像Ken建议的那样使用SCOPE_IDENTITY更安全和更具未来性。请参阅http://msdn.microsoft.com/en-us/library/ms190315.aspx。 - EventHorizon

3
INSERT INTO TableName (Field1, Field2, Field3) VALUES (1, 2, 3);
SELECT SCOPE_IDENTITY();

这是一个多语句批处理,所以我不能确定每个客户端库都会以相同的方式返回值;例如,在经典的 ADO 中,你可能需要先进入下一个记录集才能读取值。但如果你使用 ADO.NET,我知道你可以在上面的整个字符串上直接使用 ExecuteScalar,它将很好地返回你的 SCOPE_IDENTITY 值。
注意:ADO.NET 将返回值作为一个 decimal,而不是像你期望的那样的 int。这是因为,由于某种原因,SCOPE_IDENTITY 的类型为 numeric(38,0)。因此,你需要在将 ExecuteScalar 结果转换为 int 之前将其转换为 decimal,或者你需要执行 SELECT CAST(SCOPE_IDENTITY() AS INT)(假设你的 IDENTITY 字段是 INT,而不是一些更大的数值类型)。

3
我会始终使用SCOPE_IDENTITY而不是@@IDENTITY。 - marc_s
我甚至不知道SCOPE_IDENTITY,但看起来你是对的。经过几分钟的浏览,似乎需要一些奇特的情况(比如INSERT触发器在其他表中进行更多的INSERT)才能使@@IDENTITY出错;但是,你是对的,SCOPE_IDENTITY是正确的方法。我已经更新了我的答案。 - Joe White

1

你可以使用这个

Insert into Table(Col2, Col3) 
output inserted.Id
values ('xyz', 'abc')

其中Id是您的标识字段


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接