Клонирование записи и разделение ее детей между ними - PullRequest
0 голосов
/ 04 июня 2011

У меня есть две таблицы, которые выглядят примерно так:

 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), а затем повторно назначить BarFooID BarID-6 & 7 в FooID-7, а затем обновить FooType FooID-7 до его нового значения.

Мой ожидаемый результат будет выглядеть примерно так:

 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 голосов
/ 04 июня 2011

Настройка таблицы с использованием табличной переменной для удобства тестирования.Я предполагаю, что 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...