TL;博士
使用SQLServer 2005(我们支持的最小值),是否可以在不使用游标的情况下从链接表中复制数据?
详情
我有两张表格,结构粗略......
dbo.[ParentTable]
[ItemId] [UserId] [Details]
1 1 'One'
2 1 'Two'
dbo.[ChildTable]
[ChildId] [ItemId] [Details]
1 1 'One A'
2 1 'One B'
3 2 'Two A'
4 2 'Two B'
ParentTable.ItemId
是具有身份(1,1)的PK
ChildTable.ChildId
是具有身份(1,1)的PK
ChildTable.ItemId
是FK到ParentTable.ItemId
目前,如果我需要将UserId=1
的所有数据复制到UserId=2
,我必须执行以下操作...
DECLARE @ItemId INT, @NewItemId INT
DECLARE [ParentCursor] CURSOR FOR
SELECT [ItemId]
FROM [ParentTable]
WHERE [UserId] = 1
OPEN [ParentCursor]
FETCH NEXT FROM [ParentCursor] INTO @ItemId
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO [ParentTable] ([UserId], [Details])
SELECT 2, [Details]
FROM [ParentTable]
WHERE [ItemId] = @ItemId
SET @NewItemId = @@IDENTITY
INSERT INTO [ChildTable] ([ItemId], [Details]
SELECT @NewItemId, [Details]
FROM [ChildTable]
WHERE [ItemId] = @ItemId
FETCH NEXT FROM [ParentCursor] INTO @ItemId
END
CLOSE [ParentCursor]
DEALLOCATE [ParentCursor]
这实现了......的预期结果。
dbo.[ParentTable]
[ItemId] [UserId] [Details]
1 1 'One'
2 1 'Two'
3 2 'One'
4 2 'Two'
dbo.[ChildTable]
[ChildId] [ItemId] [Details]
1 1 'One A'
2 1 'One B'
3 2 'Two A'
4 2 'Two B'
5 3 'One A'
6 3 'One B'
7 4 'Two A'
8 4 'Two B'
有没有一种更简单的方法可以不使用游标?
(注意,我已经尝试创建http://sqlfiddle.com,但我根本无法正确使用游标。与分隔符有关,但我无法弄清楚。)
答案 0 :(得分:0)
像这样......
declare @olduser int = 1, @newuser int = 2
set transaction isolation level serializable
begin tran
declare @max int
select @max = MAX(itemid) from ParentTable -- as a marker for new records
-- insert all the parents
insert ParentTable (userid, details)
select @newuser, details from ParentTable where userid=@olduser order by itemid
insert ChildTable (itemid, details)
select newid, details from ChildTable child
inner join
(
-- join the old parents to the new parents
select p2.itemid as oldid, p1.itemid as newid
from
(select *, ROW_NUMBER() over (order by itemid) rn from parenttable where itemid>@max) p1
inner join
(select *, ROW_NUMBER() over (order by itemid) rn from parenttable where userid=@olduser and itemid<=@max) p2
on p1.rn = p2.rn
) oldparents
on child.itemid = oldparents.oldid
commit tran