使用 T-SQL 迁移数据时维护外键引用

问题描述 投票:0回答:2

我有3张桌子。

  1. SourceTable - 包含一些数据的源表

  2. DestinationTable - 与源表具有相同架构的目标表。两个表都有类似的数据

  3. FKSourceTable - 一个完全不同的表,具有对 SourceTable 的 FK 引用

  4. FKDestinationTable - 一个完全不同的表,具有对 DestinationTable 的 FK 引用。与 FKSourceTable 具有相同的架构

现在我的任务是将一些数据从 SourceTable 迁移到 DestinationTable,并将 FKSourceTable 迁移到 FKDestinationTable

但是,我无法迁移主键,因为 DestinationTable 可能有自己的具有相同 PK 的记录,这可能会导致 PK 冲突。

DestinationTable 作为 PK 的自动标识列,当我进行批量插入时,我不指定 PK 列,因此自动标识将完成其工作。

这意味着DestinationTable中的新记录将具有全新的ID。

我遇到的问题是,将 FKSourceTable 迁移到 FKDestinationTable 时如何维护 FK 引用?当我按如下方式向 DestinationTable 进行批量插入时,我失去了对身份的跟踪:

INSERT INTO DestionationTable
    (Col1, Col2)
SELECT st.Col1, st.Col2
FROM SourceTable st

(DestionationTable 有 3 列:Id、Col1、Col2)

挑战是我无法使用 SSIS 或任何其他 ETL 解决方案。我需要能够使用简单的 SQL 脚本来完成此操作。

有人有任何想法来解决这个问题吗?我尝试过使用

OUTPUT INTO
等,但我还没有找到一种方法来保持原始 Id 和新 Id 之间的引用

非常感谢任何帮助

sql-server t-sql foreign-keys
2个回答
3
投票

这可能不是最佳解决方案,但它应该可以完成工作。

想法是禁用身份插入并根据表中已有的内容自行生成 ID。

它的作用是迭代源数据并将其一次一行插入到目标表中。

请在执行之前彻底检查此代码,因为我自己没有测试过此代码

declare @col1 varchar(20)
declare @col2 varchar(20)
declare @col3 varchar(20)
declare @new_id int

set identity_insert on

declare source_data cursor for
select col1, col2, colx
from SourceTable

open source_data

fetch next from source_data 
into @col1, @col2, @col3

WHILE @@FETCH_STATUS = 0
begin
  set @new_id = select MAX(ID) + 1 from SourceTable

insert into DestinationTable (ID, col1, col2, col3) values (@new_id,@col1,@col2,@col3)
-- do something similar for FKDestinationTable
insert into FKDestinationTable (ID, col1, col2, col3) values (@new_id,@col1,@col2,@col3)

fetch next from source_data
into @col1, @col2, @col3 
end 

set identity_insert off

0
投票

使用 Destination 表的 Ident_Current 将数据插入到 Destination 表中

    DECLARE @ID  INT = IDENT_CURRENT('DestionationTable')

    INSERT INTO DestionationTable
        (ID, Col1, Col2)
    SELECT @ID + ROW_NUMBER() OVER(ORDER BY st.ID),st.Col1, st.Col2
    FROM SourceTable st
    WHERE -----

现在您已了解源表中的每个 ID = 目标表中的哪个 ID。

    SELECT @ID + ROW_NUMBER() OVER(ORDER BY st.ID) [NEW_ID], st.ID [OLD_ID]
    FROM SourceTable st
    WHERE -----

注意:确保这是在事务中完成的,并且事务类型取决于这些表的使用情况

© www.soinside.com 2019 - 2024. All rights reserved.