Лучший способ перемещать данные между таблицами и генерировать сопоставление старых и новых значений идентичности - PullRequest
2 голосов
/ 19 октября 2010

Мне нужно объединить данные из 2 таблиц в третью (все имеют одну и ту же схему) и сгенерировать сопоставление старых значений идентификаторов с новыми.Очевидный подход состоит в том, чтобы перебирать исходные таблицы с помощью курсора, вставляя старые и новые значения идентичности по пути.Есть ли лучший (возможно, ориентированный на набор) способ сделать это?

ОБНОВЛЕНИЕ : один дополнительный бит информации: в таблице назначения уже есть данные.

Ответы [ 3 ]

3 голосов
/ 20 октября 2010

Создайте таблицу сопоставления со столбцом IDENTITY для нового идентификатора.Вставьте из исходных таблиц в эту таблицу, создав сопоставление.

SET IDENTITY_INSERT ON для целевой таблицы.

Вставьте в целевую таблицу исходные таблицы, присоединенные к таблице сопоставления, затем SET IDENTITY_INSERT OFF.

2 голосов
/ 25 марта 2013

Я создал таблицу сопоставления на основе предложения OUTPUT оператора MERGE. Нет IDENTITY_INSERT требуется.

В приведенном ниже примере есть RecordImportQueue и RecordDataImportQueue, а RecordDataImportQueue.RecordID - от FK до RecordImportQueue.RecordID. Данные в этих промежуточных таблицах должны идти в Record и RecordData, и FK должен быть сохранен.

RecordImportQueue to Record выполняется с помощью оператора MERGE, производящего таблицу сопоставления из его OUTPUT, а RecordDataImportQueue переходит к RecordData, используя INSERT из SELECT исходной таблицы, присоединенной к таблице сопоставления.

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;

После этого вы можете вставить записи в справочную таблицу следующим образом:

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

Хотя и после оригинального поста, я надеюсь, что это может помочь другим людям, и мне любопытны любые отзывы.

1 голос
/ 19 октября 2010

Я думаю, что временно добавлю дополнительный столбец в новую таблицу для хранения старого идентификатора. После завершения вставки вы можете извлечь сопоставление в другую таблицу и удалить столбец.

...