为什么此更新不会失败?这是预期的行为吗?

时间:2019-06-07 17:52:52

标签: sql sql-server tsql

我试图理解为什么此更新不会失败,而是更新了表,即使子查询包含不正确的列名,该列名也不在其选择的表中。如果您单独运行子查询,它将返回语法错误。更新是否应该失败并给出错误?如何解释?一位同事建议说这可能是交叉应用,这是可能吗?

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不存在。尽管如此,更新仍在表中的每一行上运行。如果您单独运行子查询,它将返回语法错误。

预期的行为是更新将失败,并且事务将被回滚

1 个答案:

答案 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)