哪一个是获取我刚刚通过插入生成的标识值的最佳选择?这些陈述对性能有什么影响?
SCOPE_IDENTITY()
MAX()
TOP 1
身份列ORDER BY IdentityColumn DESC
如果SCOPE_IDENTITY()
您要插入单行并想要检索生成的 ID,请使用此选项。
CREATE TABLE #a(identity_column INT IDENTITY(1,1), x CHAR(1));
INSERT #a(x) VALUES('a');
SELECT SCOPE_IDENTITY();
结果:
----
1
OUTPUT
*如果要插入多行并且需要检索生成的 ID*集,请使用该**子句。
INSERT #a(x)
OUTPUT inserted.identity_column
VALUES('b'),('c');
结果:
----
2
3
为什么这是最好的更快的选择?
撇开性能不谈,这些是唯一保证在默认隔离级别和/或多个用户下正确的。即使您忽略正确性方面,SQL Server 也会将插入的值保存SCOPE_IDENTITY()
在内存中,因此这自然会比针对表或系统表运行您自己的独立查询要快。
忽略正确性方面就像告诉邮递员他今天的邮件做得很好 - 他完成了他的路线比他的平均时间快了 10 分钟,问题是,没有一封邮件被送到正确的房子。
不要使用以下任何一种:
@@IDENTITY
- 因为这不能在所有场景中使用,例如当一个带有标识列的表有一个触发器,该触发器也插入到另一个具有自己的标识列的表中时——你会得到错误的值。IDENT_CURRENT()
- 我在这里详细介绍了这一点,评论也是有用的阅读,但本质上,在并发下,你经常会得到错误的答案。MAX()
或者TOP 1
- 你必须用可序列化的隔离来保护这两个语句,以确保MAX()
你得到的不是别人的。这比仅使用SCOPE_IDENTITY()
.每当您插入两行或更多行并且需要生成所有标识值时,这些函数也会失败 - 您唯一的选择是OUTPUT
子句。