带OutPut的复杂TSQL MultiRow插入

时间:2016-03-30 18:12:15

标签: tsql

我有一个临时表如下

DECLARE @InsertedRows TABLE (RevId INT, FooId INT) 

我还有另外两张桌子

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

对于Foo中的每一行,我需要a)在Revisions中插入一行,b)在@InsertedRows中插入一行,其中包含来自Foo和Revisions的相应Id值。

我尝试使用Insert Output Select编写内容,如下所示:

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

但是,输出列列表中不允许使用Foo.Id。此外,SELECT中返回的Id未插入表中,因此这是另一个问题。

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

您不能使用INSERT语句引用OUTPUT子句中的FROM表。您只能使用DELETE,UPDATE或MERGE语句执行此操作。

从OUTPUT子句(https://msdn.microsoft.com/en-us/library/ms177564.aspx

上的MSDN页面
  

from_table_name是一个列前缀,用于指定包含在中的表   使用的DELETE,UPDATE或MERGE语句的FROM子句   指定要更新或删除的行。

您可以使用MERGE语句来完成您的要求。

在下面的示例中,我将表更改为所有变量表,以便可以作为独立查询运行,并将ID列更改为IDENTITY列,这些列以不同方式递增以说明关系。

ON子句(1 = 0)将始终评估为NOT MATCHED。这意味着USING语句中的所有记录都将用于插入目标表。此外,USING语句中的FROM表可用于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 |
+-------+-------+