我试图理解为什么此更新不会失败,而是更新了表,即使子查询包含不正确的列名,该列名也不在其选择的表中。如果您单独运行子查询,它将返回语法错误。更新是否应该失败并给出错误?如何解释?一位同事建议说这可能是交叉应用,这是可能吗?
Create table MyTable(column1 nvarchar(max), column2 nvarchar(max) , exclude nvarchar(max))
Create table MyTable2(c1 varchar)
INSERT INTO MyTable (column1, column2, exclude)
VALUES
('Fred', 'Smith',0),
('John', 'Smith',0),
('Michael', 'Smith',0),
('Robert', 'Smith',0);
INSERT INTO MyTable2
( c1)
VALUES
('x' ),
('y'),
('w'),
('n')
Update [MyTable] set [exclude] = 1 where [column1] in (select [column1] from [MyTable2])
drop table MyTable
drop table MyTable2
在用于更新的子查询中,Column1不存在。尽管如此,更新仍在表中的每一行上运行。如果您单独运行子查询,它将返回语法错误。
预期的行为是更新将失败,并且事务将被回滚
答案 0 :(得分:3)
是的。预期。 [column1]在子查询的范围内,因为它存在于外部查询中。
例如,对于许多查询,例如:
Update [MyTable]
set [exclude] = 1
where exists (select * from [MyTable2] where c1 = [column1])
在子查询中引用外部查询中的列既合法又必要。
正如@IłyaBursov所指出的,这是始终为表引用加上前缀列别名的众多原因之一。
例如:
Update [MyTable] t
set t.[exclude] = 1
where t.[column1] in (select t2.[column1] from [MyTable2] t2)