我知道Scope_Identity()、Identity()、@@Identity和Ident_Current()都获取标识列的值,但我想知道其中的区别。
我所面临的部分争议是,应用于上述函数的作用域是什么意思?
我还想举一个简单的例子,说明使用它们的不同场景。
我知道Scope_Identity()、Identity()、@@Identity和Ident_Current()都获取标识列的值,但我想知道其中的区别。
我所面临的部分争议是,应用于上述函数的作用域是什么意思?
我还想举一个简单的例子,说明使用它们的不同场景。
当前回答
好问题。
@@IDENTITY: returns the last identity value generated on your SQL connection (SPID). Most of the time it will be what you want, but sometimes it isn't (like when a trigger is fired in response to an INSERT, and the trigger executes another INSERT statement). SCOPE_IDENTITY(): returns the last identity value generated in the current scope (i.e. stored procedure, trigger, function, etc). IDENT_CURRENT(): returns the last identity value for a specific table. Don't use this to get the identity value from an INSERT, it's subject to race conditions (i.e. multiple connections inserting rows on the same table). IDENTITY(): used when declaring a column in a table as an identity column.
更多参考,请参见:http://msdn.microsoft.com/en-us/library/ms187342.aspx。
总结一下:如果您正在插入行,并且希望知道刚刚插入行的标识列的值,请始终使用SCOPE_IDENTITY()。
其他回答
好问题。
@@IDENTITY: returns the last identity value generated on your SQL connection (SPID). Most of the time it will be what you want, but sometimes it isn't (like when a trigger is fired in response to an INSERT, and the trigger executes another INSERT statement). SCOPE_IDENTITY(): returns the last identity value generated in the current scope (i.e. stored procedure, trigger, function, etc). IDENT_CURRENT(): returns the last identity value for a specific table. Don't use this to get the identity value from an INSERT, it's subject to race conditions (i.e. multiple connections inserting rows on the same table). IDENTITY(): used when declaring a column in a table as an identity column.
更多参考,请参见:http://msdn.microsoft.com/en-us/library/ms187342.aspx。
总结一下:如果您正在插入行,并且希望知道刚刚插入行的标识列的值,请始终使用SCOPE_IDENTITY()。
用@@身份来澄清问题:
例如,如果您插入一个表,而该表有触发器进行插入,@@Identity将返回触发器中插入的id (log_id或其他),而scope_identity()将返回原始表中插入的id。
因此,如果没有任何触发器,scope_identity()和@@identity将返回相同的值。如果你有触发器,你需要考虑你想要什么值。
下面是书中另一个很好的解释:
As for the difference between SCOPE_IDENTITY and @@IDENTITY, suppose that you have a stored procedure P1 with three statements: - An INSERT that generates a new identity value - A call to a stored procedure P2 that also has an INSERT statement that generates a new identity value - A statement that queries the functions SCOPE_IDENTITY and @@IDENTITY The SCOPE_IDENTITY function will return the value generated by P1 (same session and scope). The @@IDENTITY function will return the value generated by P2 (same session irrespective of scope).
@@identity函数返回在同一会话中创建的最后一个标识。 scope_identity()函数返回在同一会话和同一作用域中创建的最后一个标识。 ident_current(name)返回在任何会话中为特定表或视图创建的最后一个标识。 identity()函数不是用于获取标识,而是用于在select…into查询中创建标识。
会话是数据库连接。范围是当前查询或当前存储过程。
scope_identity()和@@identity函数不同的情况是,如果您在表上有一个触发器。如果您有一个插入记录的查询,导致触发器在某处插入另一条记录,scope_identity()函数将返回查询创建的标识,而@@identity函数将返回触发器创建的标识。
因此,通常使用scope_identity()函数。
作用域是指执行INSERT语句SCOPE_IDENTITY()的代码上下文,而不是@@IDENTITY的全局作用域。
CREATE TABLE Foo(
ID INT IDENTITY(1,1),
Dummy VARCHAR(100)
)
CREATE TABLE FooLog(
ID INT IDENTITY(2,2),
LogText VARCHAR(100)
)
go
CREATE TRIGGER InsertFoo ON Foo AFTER INSERT AS
BEGIN
INSERT INTO FooLog (LogText) VALUES ('inserted Foo')
INSERT INTO FooLog (LogText) SELECT Dummy FROM inserted
END
INSERT INTO Foo (Dummy) VALUES ('x')
SELECT SCOPE_IDENTITY(), @@IDENTITY
给出不同的结果。