I have target table and a staging table, for example:
create table #Target (Id int not null IDENTITY(1,1),Value int not null)
create table #Staging (TrackingId int not null, Value int not null)
insert #Staging (TrackingId, Value) values (201,1000),(202,1000),(203,2000),(204,2000)
Note that:
- The target table has an identity column.
- The staging table has a
TrackingId
column, which is not included in the target table.
I want to insert data from my staging table to my real table such that I keep the mapping from my #Staging.TrackingId
to the newly created #Target.Id
. My output, after the insertion, should look like this:
Id, TrackingId
1, 201
2, 202
3, 203
4, 204
(any other mapping is also possible, based on the order in which the insert occurs)
I tried two things. One is an order
-ed insert
, with an output
clause. This looks neat but I'm not sure SQL Server guarantees the order:
insert into #Target (Value)
OUTPUT inserted.Id --shame ", s.TrackingId" isn't allowed...
select s.Value from #Staging s
order by s.TrackingId
I also tried using MERGE
. This works, but seems wasteful (and a little dumb):
MERGE INTO #Target
USING #Staging AS s
ON 1=2 --dummy condition, we know we want an insert
WHEN NOT MATCHED BY TARGET THEN
INSERT (Value)
VALUES (s.Value)
OUTPUT INSERTED.Id, s.TrackingId
What is the correct approach for getting the newly created identity values and keeping the relation to my original order?