2016-03-30 2 views
1

У меня есть временная таблица следующего образомкомплекса TSQL многорядная Вставка с оконечным

DECLARE @InsertedRows TABLE (RevId INT, FooId INT) 

У меня также есть две других таблицы

Foo(FooId INT, MyData NVarchar(20)) 
Revisions(RevId INT, CreatedTimeStamp DATETIME) 

Для каждой строки в Foo, мне нужно а) вставить строку в Revisions и b) вставить строку в @InsertedRows с соответствующими значениями Id из Foo и Revisions.

Я пытался писать что-то с помощью Insert Output Select следующим образом:

INSERT INTO Revisions (CURRENT_TIMESTAMP) 
OUTPUT Inserted.RevId, Foo.FooId INTO @InsertedRows 
SELECT FooId From Foo 

Однако Foo.Id не допускается в списке Output столбцов. Кроме того, идентификатор, возвращаемый в SELECT, не вставлен в таблицу, так что это еще одна проблема.

Как я могу это решить?

+0

Подготовьте полную схему (столбцы идентичности/...) и выборочные данные. http://sqlfiddle.com – lad2025

ответ

2

Вы не можете ссылаться на таблицу FROM в предложении OUTPUT с инструкцией INSERT. Вы можете сделать это только с помощью оператора DELETE, UPDATE или MERGE.

На странице MSDN на пункте OUTPUT (https://msdn.microsoft.com/en-us/library/ms177564.aspx)

from_table_name столбец префикс, который указывает таблицу, включенную в ЕКОМ в DELETE, UPDATE или MERGE заявление, которое используется для указания строк для обновления или удаления.

Вы можете использовать заявление MERGE, чтобы выполнить то, что вы просите.

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

Предложение ON (1 = 0) всегда будет оценивать NOT MATCHED. Это означает, что все записи в операторе USING будут использоваться для вставки в целевую таблицу. Кроме того, таблица FROM в операторе USING будет доступна для использования в инструкции OUTPUT.

DECLARE @Foo TABLE (FooId INT IDENTITY(1,1), MyData NVarchar(20)) 
DECLARE @Revisions TABLE (RevId INT IDENTITY(100,10), CreatedTimeStamp DATETIME) 
DECLARE @InsertedRows TABLE (RevId INT, FooId INT) 

INSERT INTO @Foo VALUES ('FooData1'), ('FooData2'), ('FooData3') 

MERGE @Revisions AS [Revisions] 
USING (SELECT FooId FROM @Foo) AS [Foo] 
ON (1=0) 
WHEN NOT MATCHED THEN 
INSERT (CreatedTimeStamp) VALUES (CURRENT_TIMESTAMP) 
OUTPUT INSERTED.RevId, Foo.FooId INTO @InsertedRows; 

SELECT * FROM @Foo 
SELECT * FROM @Revisions 
SELECT * FROM @InsertedRows 

Результаты Таблица из выше запроса

@Foo table 
+-------+----------+ 
| FooId | MyData | 
+-------+----------+ 
|  1 | FooData1 | 
|  2 | FooData2 | 
|  3 | FooData3 | 
+-------+----------+ 

@Revisions table 
+-------+-------------------------+ 
| RevId | CreatedTimeStamp  | 
+-------+-------------------------+ 
| 100 | 2016-03-31 14:48:39.733 | 
| 110 | 2016-03-31 14:48:39.733 | 
| 120 | 2016-03-31 14:48:39.733 | 
+-------+-------------------------+ 

@InsertedRows table 
+-------+-------+ 
| RevId | FooId | 
+-------+-------+ 
| 100 |  1 | 
| 110 |  2 | 
| 120 |  3 | 
+-------+-------+ 
Смежные вопросы