我想从INSERT语句中使用的SELECT语句的源表中收集一个值,该值未插入目标表中
我正在使用Microsoft SQL Server 2017
我认为以下代码说明了我要执行的操作:只需剪切并粘贴到SSMS中即可重现错误
DECLARE @CrossRef TABLE (
MyTable_ID INT,
C_C VARCHAR(10)
);
DECLARE @MyData TABLE (
A VARCHAR(10),
B VARCHAR(10),
C VARCHAR(10) );
INSERT INTO @MyData (A, B, C)
VALUES ('A1', 'B1', 'C1'), ('A2', 'B2', 'C2'),('A3', 'B3', 'C3');
DECLARE @MyTable TABLE (
ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
A VARCHAR(10),
B VARCHAR(10) );
INSERT INTO @MyTable (A, B)
OUTPUT INSERTED.Id, MyData.C
INTO @CrossRef (MyTable_ID, C_C)
SELECT A, B
FROM @MyData AS MyData
-- Error: The multi-part identifier "MyData.C" could not be bound.
-- DESIRED OUTPUT
SELECT * FROM @MyTable
/*
ID A B
----------
1 A1 B1
2 A2 B2
3 A3 B3
*/
SELECT * FROM @CrossRef
/*
MyTable_ID C_C
---------------
1 C1
2 C2
3 C3
*/
OUTPUT子句无法访问INSERTED或DELETED内部表中未包含的任何内容-这是导致错误的原因。 但是,此示例Microsoft T-SQL OUTPUT CLAUSE(尽管与DELETED有关)似乎建议您可以访问其他表。
注意-该示例已高度简化,以使问题尽可能清楚 通过其他方式获得期望的输出似乎微不足道,但就像生产中的任何东西一样,实际情况要复杂得多
答案 0 :(得分:0)
使用MERGE语句-如Tab Alleman所建议的,这里是解决方案:
DECLARE @CrossRef TABLE (
MyTable_ID INT,
C_C VARCHAR(10)
);
DECLARE @MyData TABLE (
ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
A VARCHAR(10),
B VARCHAR(10),
C VARCHAR(10) );
INSERT INTO @MyData (A, B, C)
VALUES ('A1', 'B1', 'C1'), ('A2', 'B2', 'C2'),('A3', 'B3', 'C3');
DECLARE @MyTable TABLE (
ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
A VARCHAR(10),
B VARCHAR(10) );
-- MERGE statement does UPDATE where join condition exists and INSERT where it does not
MERGE @MyTable
USING (SELECT A, B, C FROM @MyData) AS [Source]
ON (1=0) -- join never true so everything inserted, nothing updated
WHEN NOT MATCHED THEN
INSERT (A, B)
VALUES ([Source].A, [Source].B)
OUTPUT INSERTED.Id, [Source].C
INTO @CrossRef (MyTable_ID, C_C);
SELECT * FROM @MyData
SELECT * FROM @MyTable
SELECT * FROM @CrossRef