我有3张桌子。
1)SourceTable - 包含一些数据的源表
2)DestinationTable - 与Source表具有相同模式的目标表。两个表都有类似的数据
3)FKSourceTable - 一个完全不同的表,其中包含对SourceTable的FK引用
4)FKDestinationTable - 一个完全不同的表,它具有对DestinationTable的FK引用。与FKSourceTable具有相同的架构
现在我的任务是将部分数据从SourceTable迁移到DestinationTable,将FKSourceTable迁移到FKDestinationTable
但是我无法迁移主键,因为DestinationTable可能有自己的记录具有相同的PK并且可能会造成PK违规。
DestinationTable作为PK的自动标识列,当我执行批量插入时,我没有指定PK列,因此自动标识将执行其作业。
这意味着DestionationTable中的新记录将具有全新的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之间的引用
非常感谢任何帮助
谢谢 Nandun。
答案 0 :(得分: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
答案 1 :(得分: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 -----
注意:确保在事务中完成此操作,事务类型取决于这些表的用法