patternMajor
Using source columns in OUTPUT INTO clause of an INSERT statement (SQL Server)
Viewed 0 times
insertcolumnsstatementsourceintosqloutputusingserverclause
Problem
I am writing a batch processing insert statement and would like to use a temp table to keep track of inserted ID's instead of looping through the items myself and calling SCOPE_IDENTITY() for each inserted row.
The data that needs to be inserted has (temporary) ID's linking it to other data that also should be inserted into another table, so I need a cross reference of the actual Id and the temporary Id.
This is an example of what I have so far:
The problem is that I cannot get the OUTPUT INTO clause to accept the ID, I've tried
The data that needs to be inserted has (temporary) ID's linking it to other data that also should be inserted into another table, so I need a cross reference of the actual Id and the temporary Id.
This is an example of what I have so far:
-- 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 @MyCrossRefThe problem is that I cannot get the OUTPUT INTO clause to accept the ID, I've tried
@MyInsertData.ID and other tricks joining the table to itself, but nothing seems to work.Solution
Actually, you can achieve the same thing by changing your
One of the nice things about
My code may contain errors, as I haven't actually tested it. My blog post from a few years ago goes into a little more detail, including on query performance.
INSERT to a MERGE. While the MERGE statement is actually a pretty neat way to do "upserts" in SQL Server, there's nothing to stop you from using it just for the purpose of inserting:-- 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 @MyCrossRefOne of the nice things about
MERGE is that it allows you to access the source columns as well as the built-in inserted and deleted tables in the OUTPUT clause.My code may contain errors, as I haven't actually tested it. My blog post from a few years ago goes into a little more detail, including on query performance.
Code Snippets
-- 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 @MyCrossRefContext
StackExchange Database Administrators Q#191146, answer score: 44
Revisions (0)
No revisions yet.