我有一个临时表如下
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未插入表中,因此这是另一个问题。
我该如何解决这个问题?
答案 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 |
+-------+-------+