Массовая вставка данных TSQL при возврате созданных идентификаторов в исходную таблицу - PullRequest
4 голосов
/ 08 июня 2011

У меня есть две таблицы.Один называется @tempImportedData, другой - @tempEngine.У меня есть данные в @tempImportedData. Я хотел бы поместить эти данные в @tempEngine, после вставки в @tempEngine будет создан идентификатор.Я хотел бы, чтобы этот идентификатор был помещен обратно в @tempImportedData в соответствующей строке.Я считаю, что в этом и состоит цель ВЫВОДНОГО заявления.У меня почти есть рабочая копия, см. Ниже.

Declare @tempEngine as table(
     id int identity(4,1) not null
    ,c1 int
    ,c2 int
);
Declare @tempImportedData as table(
     c1 int
    ,c2 int
    ,engine_id int
);
insert into @tempImportedData  (c1, c2)
    select 1,1
    union all select 1,2
    union all select 1,3
    union all select 1,4
    union all select 2,1
    union all select 2,2
    union all select 2,3
    union all select 2,4
;
INSERT INTO @tempEngine ( c1, c2 ) 
    --OUTPUT INSERTED.c1, INSERTED.c2, INSERTED.id  INTO @tempImportedData (c1, c2, engine_id) --dups with full data
    --OUTPUT INSERTED.id  INTO @tempImportedData (engine_id) -- new rows with wanted data, but nulls for rest
    SELECT 
         c1
        ,c2
    FROM 
        @tempImportedData
;       
select * from @tempEngine ;
select * from @tempImportedData ;

Я закомментировал две строки, начинающиеся с OUTPUT.

Проблема с первым состоит в том, что он вставляет все правильные данные в @tempImportedData, поэтому в результате получается 16 строк, первые 8 совпадают с нулевым значением для engine_id, а третий столбецнулевой;остальные 8 заполнены всеми тремя столбцами.Конечный результат должен иметь 8 строк, а не 16.

Второй оператор OUTPUT имеет ту же проблему, что и первый - 16 строк вместо 8. Однако новые 8 строк содержат null, null, engine_id

Так как я могу изменить этот TSQL для обновления @ tempImportedData.engine_id без добавления новых строк?

Ответы [ 2 ]

2 голосов
/ 08 июня 2011

Вам понадобится другая табличная переменная (@temp), чтобы захватить вывод из вставки, а затем выполнить оператор обновления, используя @temp против @tempImportedData, присоединяющегося к c1 и c2. Для этого необходимо, чтобы комбинация c1 и c2 была уникальной в @tempImportedData.

Declare @temp as table(
     id int
    ,c1 int
    ,c2 int
);

INSERT INTO @tempEngine ( c1, c2 ) 
    OUTPUT INSERTED.id, INSERTED.c1, INSERTED.c2 INTO @temp
    SELECT 
         c1
        ,c2
    FROM 
        @tempImportedData
;       

UPDATE T1
  SET engine_id = T2.id
FROM @tempImportedData as T1
  INNER JOIN @temp as T2
    on T1.c1 = T2.c1 and
       T1.c2 = T2.c2
; 
0 голосов
/ 08 июня 2011

@ tempImportedData все еще содержит старые данные.Первый оператор OUTPUT, кажется, вставляет правильные данные в новые строки, но старые строки все еще там.Если вы запускаете DELETE для @tempImportedData, удаляя все строки, где engine_id равен нулю в конце вашего скрипта, вам следует оставить правильные восемь строк.

...