我应该如何获得插入行的身份?
我知道@@IDENTITY和IDENT_CURRENT和SCOPE_IDENTITY,但不理解它们所附带的含义或影响。
谁能解释一下它们的区别,以及我什么时候使用它们?
我应该如何获得插入行的身份?
我知道@@IDENTITY和IDENT_CURRENT和SCOPE_IDENTITY,但不理解它们所附带的含义或影响。
谁能解释一下它们的区别,以及我什么时候使用它们?
当前回答
@@IDENTITY返回当前会话中为所有作用域中的任何表生成的最后一个标识值。这里需要小心,因为它是跨作用域的。您可以从触发器获得一个值,而不是当前语句。 SCOPE_IDENTITY()返回当前会话和当前作用域中为任何表生成的最后一个标识值。通常是你想用的。 IDENT_CURRENT('tableName')返回在任何会话和任何范围内为特定表生成的最后一个标识值。这允许您指定需要从哪个表中获取值,以防上面两个表不是您所需要的(非常罕见)。另外,正如@Guy Starbuck所提到的,“如果您想获得尚未插入记录的表的当前IDENTITY值,则可以使用此方法。” INSERT语句的OUTPUT子句将允许您访问通过该语句插入的每一行。因为它的作用域是特定的语句,所以它比上面的其他函数更直接。但是,它有点啰嗦(您需要将变量/temp表插入到表中,然后再查询),即使在回滚语句的错误场景中,它也会给出结果。也就是说,如果您的查询使用并行执行计划,这是获得标识的唯一保证方法(除了关闭并行)。但是,它在触发器之前执行,不能用于返回触发器生成的值。
其他回答
在你的插入语句之后,你需要添加这个。确认插入数据的表名。您将得到当前行,而不是刚才插入语句所影响的行。
IDENT_CURRENT('tableName')
我和其他人说的是一样的,所以每个人都是对的,我只是想让它更清楚。
@@IDENTITY返回客户端连接到数据库时插入的最后一个对象的id。 大多数情况下,这工作得很好,但有时触发器会插入一个您不知道的新行,您将从这个新行获得ID,而不是您想要的行
SCOPE_IDENTITY()解决了这个问题。它返回您在发送给数据库的SQL代码中插入的最后一个内容的id。如果触发器去创建额外的行,它们不会导致返回错误的值。万岁
IDENT_CURRENT返回任何人插入的最后一个ID。如果其他应用在不幸的时间插入了另一行,你会得到那一行的ID,而不是你的。
如果想要安全起见,请始终使用SCOPE_IDENTITY()。如果您坚持使用@@IDENTITY,然后有人决定稍后添加一个触发器,那么您的所有代码都将崩溃。
Add
SELECT CAST(scope_identity() AS int);
插入SQL语句的末尾
NewId = command.ExecuteScalar()
会取回它。
获取新插入行的标识的最好(也就是最安全的)方法是使用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)
@@IDENTITY返回当前会话中为所有作用域中的任何表生成的最后一个标识值。这里需要小心,因为它是跨作用域的。您可以从触发器获得一个值,而不是当前语句。 SCOPE_IDENTITY()返回当前会话和当前作用域中为任何表生成的最后一个标识值。通常是你想用的。 IDENT_CURRENT('tableName')返回在任何会话和任何范围内为特定表生成的最后一个标识值。这允许您指定需要从哪个表中获取值,以防上面两个表不是您所需要的(非常罕见)。另外,正如@Guy Starbuck所提到的,“如果您想获得尚未插入记录的表的当前IDENTITY值,则可以使用此方法。” INSERT语句的OUTPUT子句将允许您访问通过该语句插入的每一行。因为它的作用域是特定的语句,所以它比上面的其他函数更直接。但是,它有点啰嗦(您需要将变量/temp表插入到表中,然后再查询),即使在回滚语句的错误场景中,它也会给出结果。也就是说,如果您的查询使用并行执行计划,这是获得标识的唯一保证方法(除了关闭并行)。但是,它在触发器之前执行,不能用于返回触发器生成的值。