开发者

Cloning a record and dividing up its children between the two of them

I have two tables that look something like the following:

 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's 6 and 7 were mistakenly associated with FooID3 and should have been associated with a different Foo, with a different Foo Type. I have BarID-6 & 7 listed in a separate table (BadBar)

What I'd like to do is copy FooID-3 to a new record (FooID-7) and then repoint BarID-6 & 7's BarFooID at FooID-7, and then update FooID-7's FooType to its new value.

My expected out put would look something like this:

 Foo
 ---
 FooID  FooType
 -----  -------
 1      Red
 2      Red
 3   开发者_StackOverflow中文版   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

I can imagine how to do this in pseudo code:

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

Is there a way I can create an SQL transaction to do this as one operation or at least clone the Foo and relink the Bar to the clone (I can always make a second pass to update the clones).

Or am I stuck writing a one off script for this?


Table setup using table variable for easy testing. I assume that FooID and BarID is identity columns.

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
)

Insert sample data. This syntax works in 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)

The script:

-- 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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜