克隆记录并将其子女划分为两个

时间:2011-06-03 21:49:14

标签: sql tsql

我有两个表格如下所示:

 Foo
 ---
 FooID  FooType
 -----  -------
 1      Red
 2      Red
 3      Green
 4      Red
 5      Blue
 6      Red

 Bar
 ---    
 BarID  BarFooID  BarData
 -----  --------  -------
 1      1         A
 2      1         B
 3      2         C
 4      2         D
 5      3         E
 6      3         F
 7      3         G
 8      3         H

BarID的6和7错误地与FooID3相关联,并且应该与不同的Foo关联,具有不同的Foo类型。我有BarID-6& 7列在另一张表(BadBar)中

我想做的是将FooID-3复制到新记录(FooID-7),然后重新命名BarID-6& 7是FooID-7的BarFooID,然后将FooID-7的FooType更新为新值。

我的预期出局看起来像这样:

 Foo
 ---
 FooID  FooType
 -----  -------
 1      Red
 2      Red
 3      Green
 4      Red
 5      Blue
 6      Red
 7      Purple     // new row

 Bar
 ---    
 BarID  BarFooID  BarData
 -----  --------  -------
 1      1         A
 2      1         B
 3      2         C
 4      2         D
 5      3         E
 6      7         F        // updated
 7      7         G        // updated
 8      3         H

我可以想象如何在伪代码中执行此操作:

For Each Bar in BadBars
    copy Bar's Foo to a new Foo
    remember the new Foo's FooID
    update the new Foo's FooType
    update Bar's BarFooID to the remembered FooID
End For

有没有办法可以创建一个SQL事务来执行此操作作为一个操作或至少克隆Foo并将Bar重新链接到克隆(我总是可以进行第二次更新以更新克隆)。

或者我为此写了一个关闭脚本?

1 个答案:

答案 0 :(得分:0)

使用表变量进行表设置以便于测试。我假设FooID和BarID是标识列。

declare @Foo table 
(
  FooID int identity primary key,
  FooType varchar(10)
)

declare @Bar table 
(
  BarID int identity primary key,
  BarFooID int,
  BarData char(1)
)
declare @BadBar table 
(
  BarID int
)

插入样本数据。此语法适用于SQL Server 2008:

insert into @Foo values
('Red'),
('Red'),
('Green'),
('Red'),
('Blue'),
('Red')

insert into @Bar values
(1, 'A'),
(1, 'B'),
(2, 'C'),
(2, 'D'),
(3, 'E'),
(3, 'F'),
(3, 'G'),
(3, 'H')

insert into @BadBar values
(6),
(7)

剧本:

-- Variable to hold the the new FooID
declare @NewFooID int

-- Copy FooID 3 to new Foo row
insert into @Foo (FooType)
select FooType
from @Foo
where FooID = 3

-- Capture the new auto created FooID
set @NewFooID = scope_identity()

-- Update BarFooID in Bar for all BarID in BadBar with new FooID
update B
set BarFooID = @NewFooID
from @Bar as B
  inner join @BadBar as BB
    on B.BarID = BB.BarID

-- Change FooType for newly created Foo
-- This step is not really necessary because you could
-- use 'Purple' in the insert statement above instead
update @Foo
set FooType = 'Purple'
where FooID = @NewFooID