Pregunta

Here's the scenario:

I'm migrating data from an old system to a new system.

The old system had 2 tables that represented comments and their replies.

The new system has a single table for comments that allows nested comments. So, it has a self-referencing foreign key.

I need to move data from the 2 tables into 1.

Here's the problem: While I know which sub-comments are related to which parent comments, while I'm doing the inserting into the new table, I do not know the new ID for the parent comment.

I have considered using a while loop to loop through each of the parent comments then perform the 2 inserts inside the loop.

Is this an appropriate time to use a cursor? Per the recommendation of nearly everyone, I avoid them like the plague.

Can you think of a different approach to move the data from 2 tables into 1?

All of this is happening inside of another while loop. I'm also wondering if I should try to break this loop out into a separate loop instead of nesting them.

¿Fue útil?

Solución 3

So it looks like if I were using SQL 2008 or above, I could use the MERGE statement with the OUTPUT keyword. Unfortunately, I need to support SQL 2005 which does not have the MERGE statement. I ended up using nested loops.

Otros consejos

Without a test database in front of me, you can do it using the OUTPUT keyword in MSSQL. Should be enough to get you started:

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

If I understood your problem, you can do the insert in two phases, firstr insert of comments keeping the old ids in your table to make the second insert of child (old replies) with reference to old comments.

You could also use a separate table for ids if you don't want to alter your new table

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top