I created a mapping table based on the OUTPUT
clause of the MERGE
statement. No IDENTITY_INSERT
required.
In the example below, there is RecordImportQueue
and RecordDataImportQueue
, and RecordDataImportQueue.RecordID
is a FK to RecordImportQueue.RecordID
. The data in these staging tables needs to go to Record
and RecordData
, and FK must be preserved.
RecordImportQueue to Record is done using a MERGE
statement, producing a mapping table from its OUTPUT
, and RecordDataImportQueue goes to RecordData
using an INSERT
from a SELECT of the source table joined to the mapping table.
DECLARE @MappingTable table ([NewRecordID] [bigint],[OldRecordID] [bigint])
MERGE [dbo].[Record] AS target
USING (SELECT [InstanceID]
,RecordID AS RecordID_Original
,[Status]
FROM [RecordImportQueue]
) AS source
ON (target.RecordID = NULL) -- can never match as RecordID is IDENTITY NOT NULL.
WHEN NOT MATCHED THEN
INSERT ([InstanceID],[Status])
VALUES (source.[InstanceID],source.[Status])
OUTPUT inserted.RecordID, source.RecordID_Original INTO @MappingTable;
After that, you can insert the records in a referencing table as folows:
INSERT INTO [dbo].[RecordData]
([InstanceID]
,[RecordID]
,[Status])
SELECT [InstanceID]
,mt.NewRecordID -- the new RecordID from the mappingtable
,[Status]
FROM [dbo].[RecordDataImportQueue] AS rdiq
JOIN @MappingTable AS mt
ON rdiq.RecordID = mt.OldRecordID
Although long after the original post, I hope this can help other people, and I'm curious for any feedback.