Вставка повторяющейся записи в таблицы Master-Detail с использованием хранимой процедуры - PullRequest
1 голос
/ 17 марта 2011

У меня есть следующая структура базы данных

    Table1
============
T1ID
Fld1

    Table2
============
T2ID
T1ID(Foreign Key from Table1)
Fld1

    Table3
============
T3ID
T2ID(Foreign Key from Table2)
Fld1

Теперь сначала я отфильтрую данные Table2 и Table3 на основе T1ID.

После этого мне потребуется дублироватьэти отфильтрованные записи в тех же таблицах.Я хочу сделать это с помощью хранимой процедуры.Я видел примеры, в которых данные дублируются в одной таблице, но я не знаю, как этого добиться в этих двух основных таблицах подробностей.

Ответы [ 2 ]

1 голос
/ 17 марта 2011
declare @T1ID int = 1

declare @T table(OldT2ID int, NewT2ID int)

merge Table2 as T
using (select T2ID, Fld1
       from Table2
       where T1ID = @T1ID) as S
on (0 = 1)
when not matched then
  insert (T1ID, Fld1) values (@T1ID, S.Fld1)
output S.T2ID, inserted.T2ID into @T;

insert into Table3(T2ID, Fld1)
select T.NewT2ID, T3.Fld1
from Table3 as T3
  inner join @T as T
    on T3.T2ID = T.OldT2ID
0 голосов
/ 18 марта 2011

Я предполагаю, что T1ID, T2ID, T3ID являются идентичностями с положительным приращением. Я использую два трюка:

1) при вставке новых значений в таблицу, чтобы отличать старые значения от новых, я использую значение столбца идентификаторов. Если это больше, чем последний увиденный максимум, то это вновь добавленное значение. Однако, чтобы это оставалось верным, нам нужно убедиться, что никакие другие значения не были добавлены в таблицу, поэтому я устанавливаю уровень изоляции транзакции в сериализуемый.

2) Я создаю временный столбец в таблице 2, чтобы я мог отслеживать старые t2id для вновь вставленных. Я опускаю столбец в конце операции.

А теперь код:

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DoIt]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[DoIt]
GO

CREATE PROCEDURE [dbo].[DoIt]
    @T1ID int
AS
BEGIN
    declare @T1IDString nvarchar(10) = cast(@T1ID as nvarchar(10))
    declare @sql nvarchar(255)
    declare @Table2max nvarchar(10)

    set transaction isolation level serializable
    begin transaction

    select @Table2max = cast(max(T2ID) as nvarchar(10)) from Table2

    exec dbo.sp_executesql @statement = N'alter table Table2 add [oldT2ID] [int] null'

    set @sql = N'insert into Table2 (T1ID,fld1,oldT2ID) select T1ID,fld1,T2ID from Table2 where T1ID = ' + @T1IDString

    EXEC dbo.sp_executesql @statement = @sql

    set @sql = N'insert into Table3 select t2.T2ID, t3.fld1 from Table3 t3 join Table2 t2 on t3.T2ID = t2.oldT2ID where t2.T1ID = ' 
        + @T1IDString + ' and t2.T2ID > ' + @Table2max
    exec dbo.sp_executesql @statement = @sql

    exec dbo.sp_executesql @statement = N'alter table Table2 drop column [oldT2ID]'
    commit transaction

END

GO
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...