| 函式 | 範圍 | 回傳值 | 適用場景 |
|---|---|---|---|
@@IDENTITY |
目前連接,跨作用域 | 最後插入的 Identity 值(含觸發器插入的其他資料表) | 舊版相容,**不建議新專案使用** |
SCOPE_IDENTITY() |
目前作用域 (Stored Procedure, Trigger, Batch) | 目前作用域最後插入的 Identity 值 | 最推薦,避免觸發器干擾 |
IDENT_CURRENT('table_name') |
指定資料表,跨連接、跨作用域 | 該資料表最後產生的 Identity 值(任何連接) | 需跨連接查詢特定表最新值時 |
CREATE TABLE T1 (ID INT IDENTITY, Val INT);
CREATE TABLE T2 (ID INT IDENTITY, Val INT);
GO
CREATE TRIGGER trg_T1_Ins ON T1 AFTER INSERT AS
BEGIN
INSERT INTO T2 (Val) SELECT Val FROM inserted; -- 觸發器插入另一張表
END
GO
-- 測試
INSERT INTO T1 (Val) VALUES (100);
SELECT @@IDENTITY; -- 回傳 T2 的 ID (錯誤!)
SELECT SCOPE_IDENTITY(); -- 回傳 T1 的 ID (正確!)
-- 儲存程序中插入並回傳新 ID
CREATE PROCEDURE InsertOrder
@CustomerID INT,
@OrderDate DATETIME,
@NewOrderID INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO Orders (CustomerID, OrderDate) VALUES (@CustomerID, @OrderDate);
SET @NewOrderID = SCOPE_IDENTITY(); -- 安全取得剛插入的 Identity
END
<%
Dim conn, rs, cmd, newID
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "Provider=SQLOLEDB;Data Source=.;Initial Catalog=Northwind;User ID=sa;Password=;"
Set cmd = Server.CreateObject("ADODB.Command")
cmd.ActiveConnection = conn
cmd.CommandText = "InsertOrder"
cmd.CommandType = 4 ' adCmdStoredProc
cmd.Parameters.Append cmd.CreateParameter("@CustomerID", 3, 1, , 1) ' adInteger, adParamInput
cmd.Parameters.Append cmd.CreateParameter("@OrderDate", 7, 1, , Now()) ' adDate
cmd.Parameters.Append cmd.CreateParameter("@NewOrderID", 3, 2, , 0) ' adParamOutput
cmd.Execute
newID = cmd.Parameters("@NewOrderID").Value
Response.Write "新訂單 ID: " & newID
cmd.Parameters.Clear
Set cmd = Nothing
conn.Close
Set conn = Nothing
%>
永遠使用 SCOPE_IDENTITY()** 取得剛插入記錄的 Identity 值,除非您明確需要跨作用域或跨連接查詢特定資料表的最新值(才用 IDENT_CURRENT)。避免使用 @@IDENTITY。