| 函數 | 範圍 | 觸發器/巢狀影響 | 典型用途 |
|---|---|---|---|
SCOPE_IDENTITY() | 當前作用域 (批次/程序/觸發器/函數) | 不受 觸發器/巢狀插入影響 | 應用程式取得剛插入列的 ID (最推薦) |
@@IDENTITY | 當前連線 (Session) | 受 觸發器/巢狀插入影響,回傳最後產生的身分值 | 跨作用域追蹤、舊版相容 |
IDENT_CURRENT('table') | 指定資料表 (跨所有 Session) | 完全獨立,任何 Session 對該表的最後插入 | 監控/稽核、多連線環境 |
USE tempdb;
GO
CREATE TABLE T1 (ID INT IDENTITY, Col INT);
CREATE TABLE T2 (ID INT IDENTITY, Col INT);
GO
CREATE TRIGGER TR_T2_Ins ON T2 FOR INSERT AS
INSERT T1 SELECT 3; -- 觸發器在 T1 產生新身分值
GO
-- 測試 1:插入 T2
INSERT T2 VALUES (1);
SELECT SCOPE_IDENTITY() AS ScopeID, @@IDENTITY AS AtAtID,
IDENT_CURRENT('T1') AS CurrT1, IDENT_CURRENT('T2') AS CurrT2;
-- 結果: ScopeID=1, AtAtID=3, CurrT1=3, CurrT2=1
-- 測試 2:直接插入 T1
INSERT T1 VALUES (10);
SELECT SCOPE_IDENTITY() AS ScopeID, @@IDENTITY AS AtAtID,
IDENT_CURRENT('T1') AS CurrT1, IDENT_CURRENT('T2') AS CurrT2;
-- 結果: ScopeID=2, AtAtID=2, CurrT1=2, CurrT2=1
SCOPE_IDENTITY() (安全、精準)。@@IDENTITY (謹慎使用)。IDENT_CURRENT('Table')。@@IDENTITY 會取到觸發器產生的 ID,導致應用程式拿到錯誤值。@@IDENTITY 可能受複寫觸發器干擾。IDENT_CURRENT 非交易安全,高併發下可能讀到其他 Session 的值。INSERT INTO Table (...) OUTPUT INSERTED.ID VALUES (...);
OUTPUT 子句直接回傳插入列的身分值,完全避開上述函數的所有範圍歧義,效能也最佳。
理解三函數的作用域邊界,是正確取得身分值的關鍵。