@@IDENTITY与SCOPE_IDENTITY()_数据库文摘

在一条 INSERT、SELECT INTO 或大容量复制语句完成后,@@IDENTITY 中包含语句生成的最后一个标识值。如果语句未影响任何包含标识列的表,则 @@IDENTITY 返回 NULL。如果插入了多个行,生成了多个标识值,则 @@IDENTITY 将返回最后生成的标识值。如果语句触发了一个或多个触发器,该触发器又执行了生成标识值的插入操作,那么,在语句执行后立即调用 @@IDENTITY 将返回触发器生成的最后一个标识值。如果对包含标识列的表执行插入操作后触发了触发器,并且触发器对另一个没有标识列的表执行了插入操作,则 @@IDENTITY 将返回第一次插入的标识值。出现 INSERT 或 SELECT INTO 语句失败或大容量复制失败,或者事务被回滚的情况时,@@IDENTITY 值不会恢复为以前的设置。

      如果语句和事务失败,它们会更改表的当前标识,从而使标识列中的值出现不连贯现象。即使未提交试图向表中插入值的事务,也永远无法回滚标识值。例如,如果因 IGNORE_DUP_KEY 冲突而导致 INSERT 语句失败,表的当前标识值仍然会增加。

     @@IDENTITY、SCOPE_IDENTITY 和 IDENT_CURRENT 是相似的函数,因为他们都返回插入到表的 IDENTITY 列的最后一个值。

     @@IDENTITY 和 SCOPE_IDENTITY 可以返回当前会话中的所有表中生成的最后一个标识值。但是,SCOPE_IDENTITY 只在当前作用域内返回值,而 @@IDENTITY 不限于特定的作用域。

     IDENT_CURRENT 不受作用域和会话的限制,而受限于指定的表。IDENT_CURRENT 可以返回任何会话和任何作用域中为特定表生成的标识值。

     @@IDENTITY 函数的作用域是执行该函数的本地服务器上的当前会话。此函数不能应用于远程或链接服务器。若要获得其他服务器上的标识值,请在远程服务器或链接服务器上执行存储过程,并使(在远程或链接服务器的环境中执行的)该存储过程收集标识值,并将其返回本地服务器上的发出调用的连接。

     以下示例向包含标识列 (LocationID) 的表中插入一行,并使用 @@IDENTITY 显示新行中使用的标识值:

复制代码 代码如下:

USE AdventureWorks;
GO
--Display the value of LocationID in the last row in the table.
SELECT MAX(LocationID) FROM Production.Location;
GO
INSERT INTO Production.Location (Name, CostRate, Availability, ModifiedDate)
VALUES ('Damaged Goods', 5, 2.5, GETDATE());
GO
SELECT @@IDENTITY AS 'Identity';
GO
--Display the value of LocationID of the newly inserted row.
SELECT MAX(LocationID) FROM Production.Location;
GO

补充:
  我们要慎用@@IDENTITY,原因是 @@IDENTITY 它总是获取最后一条变更数据的自增字段的值,
 而忽略了进行变更操作所在的范围约束。比如,我有表 A 和表 B 两个表,现在我在表 A 上定义了一个Insert触发器,当在表 A 中插入一条数据时,自动在表 B 也插入一条数据。此时,大家注意,有两个原子操作:在A中插入一条数据, 接着在B中随后插入一条数据。

   现在我们想下,假设上面表 A 和表 B 都有IDENTITY自增域,那么我们在表 A 插入一条数据后,使用了 SELECT @@IDENTITY 输出时,输出的到底是 A 还是 B 的自增域的值呢?  答案很明显,是谁最后插入就输出谁,那么就是 B 了。于是,我本意是想得到 A 的自增域值,结果得到了 B 的自增域值,一只 BUG 随之诞生,搞不好还会影响到整个系统数据的混乱。

   因此,对于这种情况,建议大家慎用 @@IDENTITY,而尽量采用 SCOPE_IDENTITY()函数替换之。SCOPE_IDENTITY() 也是得到最后一条自增域的值,但是它是仅限在一个操作范围之内,而不@@IDENTITY 是取全局操作的最后一步操作所产生的自增域的值的。

时间: 2024-10-25 08:10:32

@@IDENTITY与SCOPE_IDENTITY()_数据库文摘的相关文章

数据库连接方式汇总_数据库文摘

 1.Access数据库的DSN-less连接方法:   复制代码 代码如下: set adocon=Server.Createobject("adodb.connection")adoconn.Open"Driver={Microsoft Access Driver(*.mdb)};DBQ="& _Server.MapPath("数据库所在路径")   2.Access OLE DB连接方法:   复制代码 代码如下: set adoc

sql 中获取最后生成的标识值 IDENT_CURRENT ,@@IDENTITY ,SCOPE_IDENTITY 的用法和区别

原文:sql 中获取最后生成的标识值 IDENT_CURRENT ,@@IDENTITY ,SCOPE_IDENTITY 的用法和区别 IDENT_CURRENT 返回为任何会话和任何作用域中的指定表最后生成的标识值. 语法 IDENT_CURRENT('table_name') 参数 table_name 是将要返回其标识值的表的名称.table_name 的数据类型为 varchar,没有默认值. 返回类型 sql_variant 注释 IDENT_CURRENT 类似于 Microsoft

SQL Server返回最后一个标识值的三个函数:IDENT_CURRENT、@@IDENTITY、SCOPE_IDENTITY

昨天有人在群里讨论SQL Server返回最后一个标识值的三个函数:IDENT_CURRENT.@@IDENTITY.SCOPE_IDENTITY,在些作个标记和小结. 其实MSDN对此有官方解释:这三个函数都返回最后生成的标识值. 但是,上述每个函数中定义的"最后"的作用域和会话有所不同. 1.IDENT_CURRENT 返回为某个会话和当前作用域中的指定表生成的最新标识值. 如果 IDENT_CURRENT 值为 NULL(因为表从未包含行或已被截断),IDENT_CURRENT

未在本地计算机上注册“Microsoft.Jet.OleDb.4.0”提供程序错误的解决方法_数据库其它

最近在做一个导入Excel数据到数据库的程序出现了如下错误: 计算机上注册Microsoft.Jet.OleDb.4.0提供程序错误的解决方法_数据库其它-microsoft.jet.oledb"> 运行环境 数据库:SqlServer2008 R2 OS:Windows Server 2008 R2 IIS:IIS7 解决方法 在应用程序对用的应用程序池的高级设置中设置"启用32位应用程序"为"True"

@@IDENTITY与SCOPE_IDENTITY() 及IDENT_CURRENT 的区别

本文转载:http://www.cnblogs.com/lovemyth/archive/2007/03/14/674584.html     在一条 INSERT.SELECT INTO 或大容量复制语句完成后,@@IDENTITY 中包含语句生成的最后一个标识值.如果语句未影响任何包含标识列的表,则 @@IDENTITY 返回 NULL.如果插入了多个行,生成了多个标识值,则 @@IDENTITY 将返回最后生成的标识值.如果语句触发了一个或多个触发器,该触发器又执行了生成标识值的插入操作,

Access与sql server的语法区别总结_数据库其它

下边列出sql server与access的语法差别,方便更换程序数据库时查询. 日期分隔符号 access:英镑符(#) sql server:撇号(') Boolean 常量 access:True.False:On.Off:Yes.No:整数:-1(真).0(假). sql server:整数:1(真).0(假) 字符串连接 access:和号(&) sql server:加号(+) 通配符 access:星号(*)与零个或更多字符匹配.  问号(?)与单个字符匹配. 叹号(!)意味着不在

asp经典入门教程 在ASP中使用SQL 语句第1/2页_数据库相关

MySQL.SQL Server和mSQL都是绝佳的SQL工具,可惜,在ASP的环境下你却用不着它们来创建实用的SQL语句.不过,你可以利用自己掌握的Access知识以及相应的Access技能,再加上我们的提示和技巧,相信一定能成功地在你的ASP网页中加入SQL. 1. SELECT 语句 在SQL的世界里,最最基础的操作就是SELECT 语句了.在数据库工具下直接采用SQL的时候很多人都会熟悉下面的操作:SELECT whatFROM whichTableWHERE criteria 执行以上

大数据量时提高分页的效率_数据库其它

如我们在之前的教程里讨论的那样,分页可以通过两种方法来实现: 默认分页– 你仅仅只用选中data Web control的 智能标签的Enable Paging ; 然而,当你浏览页面的时候,虽然你看到的只是一小部分数据,ObjectDataSource 还是会每次都读取所有数据 自定义分页– 通过只从数据库读取用户需要浏览的那部分数据,提高了性能. 显然这种方法需要你做更多的工作. 默认的分页功能非常吸引人,因为你只需要选中一个checkbox就可以完成了.但是它每次都读取所有的数据,这种方式

Access转换成SQL Server需要注意事项整理_数据库其它

一,首先,我说的是在ACCESS2000,SQL2000之间转换,其他的我也还没有尝试过,希望大家多多试验,肯定是有办法的:  二,转换的方法  1,打开"控制面板"下"管理工具"中的"数据库源":  2,按"添加"添加一个新的数据源,在选择栏里选"Driver do microsoft Access  (*.mdb)",完成后将出现一个框,  在"数据库源"里面输入你想写的名称,我取名