sql-server - 奇怪的 @@IDENTITY 范围行为?

标签 sql-server identity-column

这方面的内容还不是很全面,但我的印象是 @@IDENTITY 给出了数据库中创建的最后一个身份的值,无论在哪里。 SCOPE_IDENTITY() 给出当前语句范围内的值。

我有一个带有标识列的表。没有触发器,只有普通表和主索引。我已在两个单独的浏览器选项卡中运行此 Web 应用程序代码:

Dim connDb As New SqlConnection(myconnectionstring)
Dim transDb As SqlTransaction = connDb.BeginTransaction()
Dim cmdInsert As New SqlCommand("INSERT INTO mytable (somecolumn) VALUES (somevalue)", conn, transDb)
Dim cmdGetIdentity As New SqlCommand("SELECT @@IDENTITY", connDb, transDb)
' Add the record, pause, get identity.
Dim iNewHosp As Int32 = cmdInsert.ExecuteNonQuery() ' Returns 1 correctly.
Threading.Thread.Sleep(5000) ' Give the other tab time to add a record.
Dim iNewID As Int32 = cmdGetIdentity.ExecuteScalar ' Returns the new ID.
' Commit trans, close, dispose, etc..

请注意,这一切都是在事务中完成的,不确定这是否会产生影响。这里使用 SQL Server 2000(不幸的是)。在 SQL2008 中也尝试过,同样的情况发生。

因此,我在一个浏览器选项卡中运行该页面,然后在其休眠时在另一个选项卡中再次运行该页面,这会添加另一条记录。我看到的“问题”是第一个选项卡返回其 INSERT 的正确 ID,其他选项卡也是如此。我认为第一个选项卡会返回最近插入的ID,即。在第二个选项卡中完成的那个?

我最初尝试使用 SCOPE_IDENTITY() 来实现此目的,但它返回 NULL,因此我尝试 @@IDENTITY 只是为了看看发生了什么。所以我有两个问题 - 为什么 SCOPE_ 返回 NULL,为什么 @@IDENTITY 返回特定于范围的结果?

最佳答案

不,@@IDENTITY 仍然仅限于同一 session 中生成的身份值。请参阅 SCOPE_IDENTITY 中的讨论:

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

(已添加强调)

范围≠ session 。这里,范围指的是例如@@IDENTITY 将返回由触发器内的 INSERT 生成的标识值。正如您还应该看到的,您的最终选项是 IDENT_CURRENT它允许您查询特定表中的最新身份值,而不管 session 如何。

关于sql-server - 奇怪的 @@IDENTITY 范围行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10632201/

相关文章:

sql - 存储过程范围: using sp from another database

SQL逆透视多列数据

sql-server - 尽管提供非空值,但 SQL Server 插入空错误

sql - SQL Server 表中存在多个标识列

sql-server - C# 如何通过 Internet 在数据库实例之间同步数据

asp.net - ELMAH 登录 SQL Server

sql - SQL Server 中带有条件的 Case 语句

r - 从矩阵的不同列获取值的向量

sql-server - SQL Server - 即使在回滚的情况下如何确保身份字段正确递增

sql - 如何获取所有具有标识列的表的列表