SQL 迁移脚本 - 嵌套循环



下面是场景:

我正在将数据从旧系统迁移到新系统。

旧系统有 2 个表格,分别代表评论及其答复。

新系统有一个允许嵌套注释的注释表。因此,它有一个自引用外键。

我需要将数据从 2 个表移动到 1 个表中。

问题是这样的:虽然我知道哪些子注释与哪些父注释相关,但在我插入新表时,我不知道父注释的新 ID。

我考虑过使用 while 循环遍历每个父注释,然后在循环内执行 2 次插入。

这是使用游标的合适时间吗?根据几乎所有人的建议,我像躲避瘟疫一样避开它们。

您能想到一种不同的方法来将数据从 2 个表移动到 1 个表吗?

所有这些都发生在另一个 while 循环中。我也想知道我是否应该尝试将这个循环分解成一个单独的循环,而不是嵌套它们。

在我面前没有测试数据库的情况下,您可以使用 MSSQL 中的 OUTPUT 关键字来完成。应该足以让你开始:

DECLARE @NewIDs Table
(
  NewID INT,
  OldID INT
)
INSERT INTO NewTable
OUTPUT NewTable.ID,
       OldTable.ID
INTO   @NewIDs
SELECT NULL As ParentCommentID, Othercolumns
FROM   OldParentTable
INSERT INTO NewTable
SELECT NewID As ParentCommentID, OtherColumns
FROM   OldChildTable
JOIN   @NewIDs NewIDs
    ON NewIDs.OldID = OldChildTable.OldParentTableID

如果我了解您的问题,您可以分两个阶段进行插入,首先插入注释,将旧 ID 保留在表中,以参考旧注释进行子项(旧回复)的第二次插入。

如果您不想更改新表,也可以为 id 使用单独的表

if object_id('oldReply') is not null
    drop table oldReply
if object_id('oldComment') is not null
    drop table oldComment
if object_id('newComment') is not null
    drop table newComment
go  
create table oldComment (
    id integer identity(1,1) primary key,
    msg varchar(64)
    )
create table oldReply(
    id integer identity(1,1)  primary key,
    msg varchar(64),
    commentId integer references oldComment(id)
    )
create table newComment (
    id integer identity(1,1) primary key,
    msg varchar(64),
    parentId integer references newComment(id),
    oldCommentId integer
)
go
insert into oldComment(msg) values ('m1'), ('m2'), ('m3')
insert into oldReply(msg, commentId) values ('r1', 1) , ('r2', 2), ('r3', 3)
select * from oldComment
select * from oldReply
insert into 
newComment( msg, oldCommentId)
    select msg, id from oldComment 
    ;
insert into newComment (msg, parentId)  
    select oldREply.msg, parent.id
    from oldReply
    inner join newComment parent on oldReply.commentId = parent.oldCommentId
    ;
--to check
select * from newComment

因此,如果我使用的是SQL 2008或更高版本,则可以将MERGE语句与OUTPUT关键字一起使用。 不幸的是,我需要支持没有MERGE语句的SQL 2005。 我最终使用了嵌套循环。

最新更新