这不是一个完整的瓶子,但我的印象是@@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 只是为了看看发生了什么。所以我有 2 个问题 - 为什么 SCOPE_ 返回 NULL,为什么 @@IDENTITY 返回特定于范围的结果?