您的位置:首页 > 运维架构

@@IDENTITY,SCOPE_IDENTITY()和IDENT_CURRENT('TableName') 用法

2015-09-10 16:00 531 查看
@@IDENTITY,SCOPE_IDENTITY()和IDENT_CURRENT('TableName') 的作用都是取得最后一个标识值,但是由于session和scope的不同,导致结果有所不同。

一,概述

1,Session和Scope的差异

SCOPE_IDENTITY 只返回插入到当前Scope中的值,受限于当前的Session。

@@IDENTITY 不受限于特定的Scope,受限于当前的Session。

IDENT_CURRENT('TableName')只跟参数指定的Table有关,不受限于特定的Scope和Session。

SCOPE_IDENTITY() 和@@IDENTITY 的作用都是取得当前Session中的任何表内所生成的最后一个标识值。在执行一条插入语句之后,使用SCOPE_IDENTITY() 和@@IDENTITY获取得插入记录的ID Value,不同之处在于,SCOPE_IDENTITY()获取的是当前Scope中的最后一个标识值,而@@IDENTITY获取的是当前session中所有Scope中最后一个标识值。由于Scope的不同,会导致返回不同的标识值。

一个触发器,一个存储过程,一个batch是一个scope。在一个batch中exec 存储过程,就会产生多个作用域,@@IDENTITY所取得的ID值是最后一个Scope产生的结果。如果要获取当前Scope中的最后一个ID值,需要使用SCOPE_IDENTITY()。

IDENT_CURRENT is similar to the identity functions SCOPE_IDENTITY and @@IDENTITY. All three functions return last-generated identity values. However, the scope and session on which last is defined in each of these functions differ:

IDENT_CURRENT returns the last identity value generated for a specific table in any session and any scope.

@@IDENTITY returns the last identity value generated for any table in the current session, across all scopes.

SCOPE_IDENTITY returns the last identity value generated for any table in the current session and the current scope.

2,ID列的特点,当语句执行失败或事务回滚时,ID值不会回滚。

Failed statements and transactions can change the current identity for a table and create gaps in the identity column values. The identity value is never rolled back even though the transaction that tried to insert the value into the table is not committed. For example, if an INSERT statement fails because of an IGNORE_DUP_KEY violation, the current identity value for the table is still incremented.

3,IDENT_CURRENT('TableName')

IDENT_CURRENT is not limited by scope and session; it is limited to a specified table. IDENT_CURRENT returns the value generated for a specific table in any session and any scope.

When the table has never contained rows or has been truncated, the IDENT_CURRENT function returns the seed value.

IDENT_CURRENT不受session和scope的限制,只跟参数指定的表相关。如果表不包含数据行或被truncate,那么IDENT_CURRENT将返回seed value。

4,SCOPE_IDENTITY()

SCOPE_IDENTITY returns the last identity value inserted into an identity column within the same and current scope.

A scope is a module: a stored procedure, trigger, function, or batch. Therefore, two statements are in the same scope if they are in the same stored procedure, function, or batch.

Scope是一个作用域,例如当前的batch是一个作用域,在表dbo.ta上创建了一个trigger,在trigger插入数据,那么trigger就是另外一个scope,这两个scope属于同一个session。

create table dbo.ta
(
id int identity(1,1) not null,
name varchar(10)
)

create table dbo.tb
(
id int identity(1,1) not null,
name varchar(10)
)

CREATE TRIGGER dbo.trg_InsertTa
ON  dbo.ta
AFTER insert
AS
BEGIN
SET NOCOUNT ON;

insert into dbo.tb
values('b')

END
GO

insert into dbo.ta
values('a')


5,@@IDENTITY

@@IDENTITY and SCOPE_IDENTITY return the last identity value generated in any table in the current session. However, SCOPE_IDENTITY returns the value only within the current scope; @@IDENTITY is not limited to a specific scope.

The scope of the @@IDENTITY function is current session on the local server on which it is executed.

@@IDENTITY返回当前session中所有scope中的最后一个identity value,@@IDENTITY is not limited to a specific scope,但是必须是当前session。

After an INSERT, SELECT INTO, or bulk copy statement is completed, @@IDENTITY contains the last identity value that is generated by the statement. If the statement did not affect any tables with identity columns, @@IDENTITY returns NULL. If multiple rows are inserted, generating multiple identity values, @@IDENTITY returns the last identity value generated. If the statement fires one or more triggers that perform inserts that generate identity values, calling @@IDENTITY immediately after the statement returns the last identity value generated by the triggers. If a trigger is fired after an insert action on a table that has an identity column, and the trigger inserts into another table that does not have an identity column, @@IDENTITY returns the identity value of the first insert. The @@IDENTITY value does not revert to a previous setting if the INSERT or SELECT INTO statement or bulk copy fails, or if the transaction is rolled back.

Failed statements and transactions can change the current identity for a table and create gaps in the identity column values. The identity value is never rolled back even though the transaction that tried to insert the value into the table is not committed. For example, if an INSERT statement fails because of an IGNORE_DUP_KEY violation, the current identity value for the table is still incremented.

二,实例

1,创建实例表格

--Session1

create table dbo.ta
(
id int identity(1,1) not null,
name varchar(10)
)

create table dbo.tb
(
id int identity(1,1) not null,
name varchar(10)
)

CREATE TRIGGER dbo.trg_InsertTa
ON  dbo.ta
AFTER insert
AS
BEGIN
SET NOCOUNT ON;

insert into dbo.tb
values('b'),('c')

END
GO


2,查看三个函数获取ID值得不同

--Session1

select @@identity as [@@identity],
SCOPE_IDENTITY() as [SCOPE_IDENTITY],
IDENT_CURRENT('tb') as [IDENT_CURRENT]




When the table has never contained rows or has been truncated, the IDENT_CURRENT function returns the seed value.

3,向表dbo.ta中插入一条数据,查看ID值的变化

--Session1

insert into dbo.ta
values('a')

select * from dbo.ta
select * from dbo.tb

select @@identity as [@@identity],
SCOPE_IDENTITY() as [SCOPE_IDENTITY],
IDENT_CURRENT('ta') as [IDENT_CURRENT_ta],
IDENT_CURRENT('tb') as [IDENT_CURRENT_tb]




@@identity返回的trigger这个scope中最后产生的ID值,scope_identity()返回的是当前scope中个最后产生的ID值。

4,new一个新的session,查看ID值

--Session2



@@identity和scope_identity()返回的值都是null,而ident_current('TableName')返回指定表的当前ID值。

5,测试事务回滚对ID值得影响

--Session2

begin tran

insert into dbo.ta
values('a')

rollback tran

select * from dbo.ta
select * from dbo.tb

select @@identity as [@@identity],
SCOPE_IDENTITY() as [SCOPE_IDENTITY],
IDENT_CURRENT('ta') as [IDENT_CURRENT_ta],
IDENT_CURRENT('tb') as [IDENT_CURRENT_tb]




即使事务回滚,ID值仍然会增加,如果一个表中含有ID列,那么ID列的值可能是不连续的。

这个结果是在Session2中进行查看的,@@IDENTITY 和 SCOPE_IDENTITY()会限于Session,那么在Session1中,ID值会变化吗?

6,返回到Session1中,查看ID值的变化

--Session1

select * from dbo.ta
select * from dbo.tb

select @@identity as [@@identity],
SCOPE_IDENTITY() as [SCOPE_IDENTITY],
IDENT_CURRENT('ta') as [IDENT_CURRENT_ta],
IDENT_CURRENT('tb') as [IDENT_CURRENT_tb]




在Session1中,,@@IDENTITY 和 SCOPE_IDENTITY()返回的ID值没有变化。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: