これについては完全なボトルではありませんが、@@IDENTITY は、どこにいても、データベースで最後に作成された ID の値を与えるという印象を受けました。SCOPE_IDENTITY() は、現在のステートメントのスコープ内の値を提供します。
ID列を持つテーブルがあります。トリガーはなく、バニラ テーブルとプライマリ インデックスのみです。この Web アプリ コードを 2 つの個別のブラウザー タブで実行しました。
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でも試してみましたが、同じことが起こります。
そのため、ブラウザの 1 つのタブでページを実行し、スリープ中に別のタブで再度実行すると、別のレコードが追加されます。私が見ている「問題」は、最初のタブが他のタブと同様に、その INSERT に対して正しいID を返すことです。最初のタブは最新の挿入の ID を返すと思いました。2番目のタブで行われたもの?
私はもともとこれに SCOPE_IDENTITY() を使用しようとしましたが、NULL を返していたので、何が起こっているのかを確認するためだけに @@IDENTITY を試しました。2 つの質問があります。なぜ SCOPE_ は NULL を返すのでしょうか? @@IDENTITY はなぜスコープ固有の結果を返すのでしょうか?