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.
SQL Migration Script - nested loops
-
30-07-2022 - |
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.
Solución 3
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