【.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吧。
參考網站: