在SQL SERVER中可以使用三种方法来获取系统生成的标识值:
@@IDENTITY、SCOPE_IDENTITY 和 IDENT_CURRENT 这三个函数都返回最后生成的标识值。但是,它们在定义"最后"的作用域和会话上不同。
@@IDENTITY
返回最后插入的标识值。
语法
@@IDENTITY
返回类型
numeric
注释
在一条 INSERT、SELECT INTO 或大容量复制语句完成后,@@IDENTITY 中包含此语句产生的最后的标识值。若此语句没有影响任何有标识列的表,则 @@IDENTITY 返回 NULL。若插入了多个行,则会产生多个标识值,@@IDENTITY 返回最后产生的标识值。如果此语句激发一个或多个执行产生标识值的插入操作的触发器,则语句执行后立即调用 @@IDENTITY 将返回由触发器产生的最后的标识值。若 INSERT 或 SELECT INTO 语句失败或大容量复制失败,或事务被回滚,则 @@IDENTITY 值不会还原为以前的设置。
如果在你进行insert操作的时间和检查@@IDENTITY的时间之间有另一个insert操作被执行,@@IDENTITY返回的不是系统为你的insert所生成的标识值,而是它为最近的一个insert操作所生成的标识值。
SCOPE_IDENTITY
返回插入到同一作用域中的 IDENTITY 列内的最后一个 IDENTITY 值。一个作用域就是一个模块——存储过程、触发器、函数或批处理。因此,如果两个语句处于同一个存储过程、函数或批处理中,则它们位于相同的作用域中。
语法
SCOPE_IDENTITY( )
返回类型
sql_variant
注释
SCOPE_IDENTITY 和 @@IDENTITY 返回在当前会话中的任何表内所生成的最后一个标识值。但是,SCOPE_IDENTITY 只返回插入到当前作用域中的值;@@IDENTITY 不受限于特定的作用域。
例如,有两个表 T1 和 T2,在 T1 上定义了一个 INSERT 触发器。当将某行插入 T1 时,触发器被激发,并在 T2 中插入一行。此例说明了两个作用域:一个是在 T1 上的插入,另一个是作为触发器的结果在 T2 上的插入。
假设 T1 和 T2 都有 IDENTITY 列,@@IDENTITY 和 SCOPE_IDENTITY 将在 T1 上的 INSERT 语句的最后返回不同的值。
@@IDENTITY 返回插入到当前会话中任何作用域内的最后一个 IDENTITY 列值,该值是插入 T2 中的值。
SCOPE_IDENTITY() 返回插入 T1 中的 IDENTITY 值,该值是发生在相同作用域中的最后一个 INSERT。如果在作用域中发生插入语句到标识列之前唤醒调用 SCOPE_IDENTITY() 函数,则该函数将返回 NULL 值。
建议使用这个方法获取系统生成的标识值,因为这是一种最安全的确定你最近生成的标识值的方法。
IDENT_CURRENT
返回为任何会话和任何作用域中的指定表最后生成的标识值。
语法
IDENT_CURRENT('table_name')
参数
table_name
是将要返回其标识值的表的名称。table_name 的数据类型为 varchar,没有默认值。
返回类型
sql_variant
注释
IDENT_CURRENT 很类似于标识函数 SCOPE_IDENTITY ,但是IDENT_CURRENT 只会返回指定表的标识值,不管对其他的表是否进行过insert操作,这样可以防止深藏在触发器中的另一个insert操作影响到这个函数的返回结果。