Insert

在 INSERT 語句的 OUTPUT INTO 子句中使用源列 (SQL Server)

  • November 19, 2017

我正在編寫批處理插入語句,並希望使用臨時表來跟踪插入的 ID,而不是自己循環遍歷項目並為每個插入的行呼叫 SCOPE_IDENTITY()。

需要插入的數據具有(臨時)ID 將其連結到也應插入另一個表的其他數據,因此我需要實際 Id 和臨時 Id 的交叉引用。

這是我到目前為止的一個例子:

-- The existing table 
DECLARE @MyTable TABLE (ID INT IDENTITY(1,1), [Name] NVARCHAR(MAX));

-- My data I want to insert
DECLARE @MyInsertData TABLE (ID INT, [Name] NVARCHAR(MAX));
INSERT INTO @MyInsertData ( ID,Name)
VALUES ( -1 , 'bla'),(-2,'test'),(-3,'last');

DECLARE @MyCrossRef TABLE ([NewId] INT, OldId INT);

INSERT INTO @MyTable ( [Name] )
  OUTPUT Inserted.ID, INS.ID INTO @MyCrossRef
  SELECT [NAME] FROM @MyInsertData INS

-- Check the result
SELECT * FROM @MyCrossRef

問題是我無法讓 OUTPUT INTO 子句接受 ID,我已經嘗試過@MyInsertData.ID將表連接到自身的其他技巧,但似乎沒有任何效果。

實際上,您可以通過將您的更改INSERTMERGE. 雖然該MERGE語句實際上是在 SQL Server 中執行“upserts”的一種非常巧妙的方法,但沒有什麼可以阻止您將其僅用於插入目的:

-- The existing table 
DECLARE @MyTable TABLE (ID INT IDENTITY(1,1), [Name] NVARCHAR(MAX));

-- My data I want to insert
DECLARE @MyInsertData TABLE (ID INT, [Name] NVARCHAR(MAX));
INSERT INTO @MyInsertData ( ID,Name)
VALUES ( -1 , 'bla'),(-2,'test'),(-3,'last');

DECLARE @MyCrossRef TABLE ([NewId] INT, OldId INT);

MERGE INTO @MyTable AS dest
USING @MyInsertData AS ins ON 1=0   -- always false

WHEN NOT MATCHED BY TARGET          -- happens for every row, because 1 is never 0
   THEN INSERT ([Name])
        VALUES (ins.[NAME])

OUTPUT inserted.ID, ins.ID
INTO @MyCrossRef (NewId, OldId);

-- Check the result
SELECT * FROM @MyCrossRef

關於它的好處之一MERGE是它允許您訪問源列以及子句中的內置inserteddeleted表。OUTPUT

我的程式碼可能包含錯誤,因為我還沒有實際測試過它。我幾年前的部落格文章更詳細地介紹了一些細節,包括查詢性能。

引用自:https://dba.stackexchange.com/questions/191146