可能重复:
获取插入行标识的最佳方法?
假设有一个大型 Web 应用程序,例如具有许多在线用户的社交网络。
用户不断向某个表插入新行。此应用程序在每次插入后都需要新行的ID ,并且此ID是自动增加的int
列。
获取最后一个 raw 的 ID 是由 SQLSELECT IDENT_CURRENT()
作为一个单独的函数调用通过 Web 应用程序为每个用户完成的。
如果多个用户同时插入行,它是否正常工作并返回正确的ID ?
可能重复:
获取插入行标识的最佳方法?
假设有一个大型 Web 应用程序,例如具有许多在线用户的社交网络。
用户不断向某个表插入新行。此应用程序在每次插入后都需要新行的ID ,并且此ID是自动增加的int
列。
获取最后一个 raw 的 ID 是由 SQLSELECT IDENT_CURRENT()
作为一个单独的函数调用通过 Web 应用程序为每个用户完成的。
如果多个用户同时插入行,它是否正常工作并返回正确的ID ?
另一个存档版本...
Insert Atab (na,nu)
OUTPUT INSERTED.id
values('Text','Add')
从受 INSERT、UPDATE、DELETE 或 MERGE 语句影响的每一行返回信息或表达式。这些结果可以返回到处理应用程序,以用于诸如确认消息、归档和其他此类应用程序要求之类的事情。结果也可以插入到表或表变量中。此外,您可以在嵌套的 INSERT、UPDATE、DELETE 或 MERGE 语句中捕获 OUTPUT 子句的结果,并将这些结果插入到目标表或视图中。
我们公司的某个人使用了 ident_current,他应该使用 scope_identity(现在应该使用 OUTPUT)。碰巧应用程序正在插入一条记录,同时正在运行数百万条记录的数据导入。在随后的记录导入中,错误的 ID 附加到了子记录,导致数据完整性问题需要很长时间才能解决。在任何情况下都不应使用 ident_current 来获取刚刚插入的值。它是数据完整性问题的保证。
如果您使用的 SQL Server 版本具有可用的 OUTPUT,则这是首选技术。OUTPUT 不仅会为您提供刚刚插入的 id,而且还可以为您提供其他插入的值,以便您可以更轻松地获取多个记录插入的值以及单个记录您还可以使用它来找出删除的内容或更新。所以它是一个非常有价值的工具。基本上,您使用所需的列设置表变量,然后在 INSERT、UPDATE 或 DELETE 中使用 OUTPUT 子句,然后您可以使用表变量来获取其他处理步骤所需的信息。一些示例可以查看您可以在插入语句中对输出执行哪些操作:
DECLARE @MyTableVar table( MyID int,
MyName varchar(50));
INSERT MyTable1 (MYName)
OUTPUT INSERTED.MyID, INSERTED.MyName
INTO @MyTableVar
VALUES ('test');
--Display the result set of the table variable.
SELECT MyID, MyName FROM @MyTableVar;
--Display the result set of the table.
Insert into table2 (MyID,test2, test2)
SELECT MyID, 'mttest1', 'mytest2' FROM @MyTableVar;
Insert into table2 (MyID,field1, InsertedDate)
SELECT MyID, s.Field1, getdate() FROM @MyTableVar t
join stagingtable s on t.MyName = s.MyName
您可能想改用 SCOPE_IDENTITY() 。以下是@@IDENTITY、IDENT_CURRENT() 和 SCOPE_IDENTITY 之间差异的细分(从这里窃取):
SELECT @@IDENTITY 它返回在连接上产生的最后一个 IDENTITY 值,而不管产生该值的表,也不管产生该值的语句的范围。@@IDENTITY 将返回在当前会话中输入到表中的最后一个标识值。虽然@@IDENTITY 仅限于当前会话,但它不限于当前范围。如果您在一个表上有一个触发器导致在另一个表中创建一个身份,您将获得最后创建的身份,即使它是创建它的触发器。
SELECT SCOPE_IDENTITY() 它返回连接上和同一范围内的语句生成的最后一个 IDENTITY 值,而不管生成该值的表。SCOPE_IDENTITY() 与@@IDENTITY 一样,将返回在当前会话中创建的最后一个身份值,但它也会将其限制在您当前的范围内。换句话说,它将返回您显式创建的最后一个身份值,而不是由触发器或用户定义的函数创建的任何身份。
SELECT IDENT_CURRENT('tablename') 它返回表中生成的最后一个 IDENTITY 值,与创建该值的连接无关,也与生成该值的语句的范围无关。IDENT_CURRENT 不受范围和会话限制;它仅限于指定的表。IDENT_CURRENT 返回为任何会话和任何范围内的特定表生成的标识值。
如您所见,SCOPE_IDENTITY() 将通过范围内的语句返回当前连接生成的最后一个 ID。根据您的要求,这听起来会更好地满足您的需求。