我应该如何获得插入行的身份?
我知道@@IDENTITY和IDENT_CURRENT和SCOPE_IDENTITY,但不理解它们所附带的含义或影响。
谁能解释一下它们的区别,以及我什么时候使用它们?
我应该如何获得插入行的身份?
我知道@@IDENTITY和IDENT_CURRENT和SCOPE_IDENTITY,但不理解它们所附带的含义或影响。
谁能解释一下它们的区别,以及我什么时候使用它们?
当前回答
在你的插入语句之后,你需要添加这个。确认插入数据的表名。您将得到当前行,而不是刚才插入语句所影响的行。
IDENT_CURRENT('tableName')
其他回答
从MSDN
@@IDENTITY、SCOPE_IDENTITY和IDENT_CURRENT是类似的函数,它们返回插入到表的IDENTITY列中的最后一个值。 @@IDENTITY和SCOPE_IDENTITY将返回当前会话中在任何表中生成的最后一个标识值。然而,SCOPE_IDENTITY只返回当前范围内的值;@@IDENTITY不受特定范围的限制。 IDENT_CURRENT不受作用域和会话的限制;它仅限于指定的表。IDENT_CURRENT返回在任何会话和任何范围内为特定表生成的标识值。有关更多信息,请参见IDENT_CURRENT。
IDENT_CURRENT是一个以表作为参数的函数。 当你在表上有一个触发器时,@@IDENTITY可能返回令人困惑的结果 大多数时候SCOPE_IDENTITY是你的英雄。
我认为检索插入的id最安全、最准确的方法是使用output子句。
例如(摘自以下MSDN文章)
使用AdventureWorks2008R2; 去 声明@MyTableVar表(NewScrapReasonID smallint, 名字varchar (50), ModifiedDate datetime); 插入生产。ScrapReason 输出插入。ScrapReasonID,插入。名字,插入。ModifiedDate 到@MyTableVar VALUES (N'操作符错误',GETDATE()); ——显示表变量的结果集。 SELECT NewScrapReasonID, Name, ModifiedDate FROM @ mytablear; ——显示表的结果集。 SELECT ScrapReasonID, Name, ModifiedDate 从Production.ScrapReason; 去
获取新插入行的标识的最好(也就是最安全的)方法是使用output子句:
create table TableWithIdentity
( IdentityColumnName int identity(1, 1) not null primary key,
... )
-- type of this table's column must match the type of the
-- identity column of the table you'll be inserting into
declare @IdentityOutput table ( ID int )
insert TableWithIdentity
( ... )
output inserted.IdentityColumnName into @IdentityOutput
values
( ... )
select @IdentityValue = (select ID from @IdentityOutput)
Add
SELECT CAST(scope_identity() AS int);
插入SQL语句的末尾
NewId = command.ExecuteScalar()
会取回它。
@@IDENTITY返回当前会话中为所有作用域中的任何表生成的最后一个标识值。这里需要小心,因为它是跨作用域的。您可以从触发器获得一个值,而不是当前语句。 SCOPE_IDENTITY()返回当前会话和当前作用域中为任何表生成的最后一个标识值。通常是你想用的。 IDENT_CURRENT('tableName')返回在任何会话和任何范围内为特定表生成的最后一个标识值。这允许您指定需要从哪个表中获取值,以防上面两个表不是您所需要的(非常罕见)。另外,正如@Guy Starbuck所提到的,“如果您想获得尚未插入记录的表的当前IDENTITY值,则可以使用此方法。” INSERT语句的OUTPUT子句将允许您访问通过该语句插入的每一行。因为它的作用域是特定的语句,所以它比上面的其他函数更直接。但是,它有点啰嗦(您需要将变量/temp表插入到表中,然后再查询),即使在回滚语句的错误场景中,它也会给出结果。也就是说,如果您的查询使用并行执行计划,这是获得标识的唯一保证方法(除了关闭并行)。但是,它在触发器之前执行,不能用于返回触发器生成的值。