2013-11-15 43 views
2

以下是此场景:SQL迁移脚本 - 嵌套循环

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

旧系统有2个表格代表注释及其回复。

新系统有一个允许嵌套评论的评论表。所以它有一个自引用的外键。

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

这里的问题: 虽然我知道哪些子评论都涉及到其父母的意见,而我做的插入到新表,我不知道父母评论的新ID。

我已经使用一个while循环遍历每个父评论然后执行循环内的2个插入考虑。

这是一个适当的时间来使用游标?根据几乎每个人的建议,我避免他们像瘟疫。

你能想出不同的方法来从2个表将数据移动到1?

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

+3

DB什么您使用的是?如果您使用SQL Server,则可以使用'OUTPUT'子句获取标识列值。更好的是,如果有序列作为主键,则可以在插入之前预先生成密钥。 – Lock

+0

MSSQL - 我不熟悉OUTPUT子句 –

+2

@SeattleLeonard IDENTITY_SCOPE()返回上次创建的增量ID。这是你需要的吗? – LINQ2Vodka

回答

0

所以它看起来像如果我使用SQL 2008或以上,我可以使用MERGE声明与OUTPUT关键字。不幸的是,我需要支持没有MERGE语句的SQL 2005。我结束了使用嵌套循环。

1

没有在我面前的测试数据库,可以使用在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 
+0

嗯,当我采取这种方法时,我得到错误“多部分标识符”OldTable.ID“无法绑定。“ –

+0

fromColumn状态的文档:是一个列前缀,它指定包含在用于指定要更新或删除的行的DELETE,UPDATE或MERGE语句的FROM子句中的表。 –

1

如果我明白你的问题,你可以插入两个阶段,注释保持旧ID在你的餐桌,参照旧的意见,使孩子(旧回复)的第二个插入firstr插入。

你也可以使用IDS单独的表,如果你不想改变你的新表

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