首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 取得新增記錄 Identity 值的兩種標準方法:OUTPUT 子句與 @@IDENTITY

     編輯:關於SqlServer

方法一:OUTPUT 子句 (SQL Server 2005+ 推薦)


INSERT INTO dbo.MyTable (Col1, Col2, Col3)
OUTPUT INSERTED.Id  -- 直接回傳剛插入列的 Identity 值
VALUES ('A', 'B', 'C');
  • **單一陳述式完成**,無併發競爭風險。
  • 可同時回傳多欄位:OUTPUT INSERTED.Id, INSERTED.CreateTime, INSERTED.Col1。
  • 支援 INSERTED.*、DELETED.* (用於 UPDATE/DELETE/MERGE)。
  • ADO.NET 呼叫:int newId = (int)cmd.ExecuteScalar();

方法二:@@IDENTITY 全域變數 (舊版相容)


INSERT INTO dbo.MyTable (Col1, Col2, Col3) VALUES ('A', 'B', 'C');
SELECT @@IDENTITY AS NewId;
  • 需**同一批次 (Batch) 連續執行** 兩條陳述式(中間無 GO)。
  • **重大缺陷**:若資料表有 **觸發器** 且觸發器內對**其他資料表**執行 INSERT,@@IDENTITY 會回傳**觸發器內最後插入的 Identity**,而非原資料表的值。
  • ADO.NET 呼叫:同樣用 ExecuteScalar() 執行批次 SQL。

補充:SCOPE_IDENTITY() 與 IDENT_CURRENT()

函數範圍適用場景風險
SCOPE_IDENTITY()目前作用域 (Batch/觸發器/程序)**最佳替代 @@IDENTITY**,免疫觸發器干擾無
IDENT_CURRENT('TableName')全伺服器、跨 Session、跨作用域稽核、報表、跨連線查詢最後值**高併發下極不準**,不建議用於取得剛插入值

最佳實踐建議

  1. 新專案一律使用 OUTPUT INSERTED.Id:語意明確、效能佳、免疫觸發器、可回傳多欄位。
  2. 維護舊代碼若用 @@IDENTITY,**立即改為 SCOPE_IDENTITY()** 修正潛在 Bug。
  3. 批次插入多筆需取回所有 Identity:
    INSERT ... OUTPUT INSERTED.Id INTO @IdTable VALUES ..., ..., ...;
  4. 避免使用 IDENT_CURRENT 取得剛插入值,僅供事後稽核參考。

結語

取得 Identity 值,**OUTPUT 子句是現代標準**,SCOPE_IDENTITY() 是舊代碼的安全替代,**@@IDENTITY 已棄用 (含觸發器 Bug)**,**IDENT_CURRENT 不適用併發插入**。選對工具,才能在高併發環境下精準拿到屬於你的那個 ID。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved