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

SQL 取得剛插入資料的自增 ID:LAST_INSERT_ID、@@IDENTITY、SCOPE_IDENTITY 差異詳解

     編輯:關於SqlServer

MySQL:LAST_INSERT_ID()

  • 基於連線,不受其他客戶端影響,無需鎖定。
  • 單一 INSERT 多列時,僅回傳第一列產生的 ID。
  • 範例:
    INSERT INTO t VALUES (NULL,'a'),(NULL,'b'),(NULL,'c');
    SELECT LAST_INSERT_ID(); -- 回傳第一列的 ID

SQL Server:三大函數比較

函數範圍觸發器影響典型用途
@@IDENTITY目前連線、所有作用域、所有資料表受觸發器插入影響(回傳觸發器中最後插入的 ID)簡單環境、無觸發器
SCOPE_IDENTITY()目前連線、目前作用域、所有資料表不受觸發器影響(回傳本作用域最後插入的 ID)推薦、最安全
IDENT_CURRENT('table')指定資料表、所有連線、所有作用域不受作用域限制,回傳該表最後產生的 ID跨連線監控、複寫稽核

觸發器情境示範

CREATE TABLE T1 (id INT IDENTITY, val VARCHAR(10));
CREATE TABLE T2 (id INT IDENTITY, val VARCHAR(10));
GO
CREATE TRIGGER trg_T1 ON T1 AFTER INSERT AS
    INSERT INTO T2 (val) SELECT 'from trigger';
GO

INSERT INTO T1 (val) VALUES ('direct');
SELECT @@IDENTITY;       -- 回傳 T2 的 ID(觸發器插入)
SELECT SCOPE_IDENTITY(); -- 回傳 T1 的 ID(本作用域)
SELECT IDENT_CURRENT('T1'), IDENT_CURRENT('T2');

並發壓測結論(摘錄)

  • @@IDENTITY 在高並發下極易衝突(萬行級即失效)。
  • SCOPE_IDENTITY() 經測試零衝突,可放心用於預存程序、觸發器巢狀。
  • IDENT_CURRENT 適合單表監控,不適用多表作用域。

最佳實務建議

  1. 預設使用 SCOPE_IDENTITY()。
  2. 若在觸發器中需取得觸發器內插入的 ID,改用 @@IDENTITY。
  3. 跨連線稽核才用 IDENT_CURRENT。
  4. Oracle 使用 RETURNING INTO、PostgreSQL 使用 RETURNING、SQLite 使用 last_insert_rowid()。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved