【MS SQL】關於 Select @@IDENTITY

【.Net】關於 Select @@IDENTITY

我要說,這是一篇紀錄著我不搞懂所有道理的文章。

以前的我,取回Insert 的識別ID寫法為,有用Transation包覆:

string SQLStr = "Insert into Live Values('123','456');Select @@Identity as A'
Dataset tDS = //上述Query取回之結果
string LiveID = tDS.Table[0].Rows[0]["A"].ToString();

上述的寫法,在大多的情況下應該都不會有錯,但是我錯了。

你很難確保有一天不會有其他人來維護或是新增你的程式。

錯誤就發生在有一個同仁,幫我新增了一個功能,同時在Live這個Table撰寫了Trigger。

該Tragger中,若是新增同時符合特定條件,則會再去另外一張Table(B) Insert 資料。

所以,悲劇就發生了。

舊有的寫法,取回的LiveID,不會是新增到Live那筆資料的識別ID,而是Table(B)的Table的識別ID。

因為,Select @@Identity會傳回所有範圍的目前工作階段中,任何資料表所產生的最後一個識別值。

原本以為用Transation包覆整段Query就沒問題的後果,就是如此,因為Trigger也在目前工作階段中。

解決方式:

取回識別值這個動作其實有三種類似方式:IDENT_CURRENT、SCOPE_IDENTITY 和 @@IDENTITY

依照我們上述狀況來說明三種函數吧!

狀況:Insert Live Table後,Trigger 會在 Insert B Table。

IDENT_CURRENT:此方式會返回指定的Table的識別值。

寫法:

SELECT IDENT_CURRENT ('TableName') AS Current_Identity;

SCOPE_IDENTITY :此方式會傳回在目前工作階段以及目前範圍中,任何資料表產生的最後一個識別值。

寫法:

SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY]
--此方法會回傳 Live Insert後的識別值

@@IDENTITY :此方式會傳回所有範圍的目前工作階段中,任何資料表所產生的最後一個識別值。

寫法:

SELECT @@IDENTITY
--此方法會回傳 B Table Insert後的識別碼


各位看官看懂了嗎!?

只能說,現在知道總比更久的未來知道的好!!

不懂就請跟我一起看MSDN吧。

 

參考網站:

SCOPE_IDENTITY

IDENT_CURRENT

@@IDENTITY