[SQL Server] 20052008 错误的子查询

    技术2025-11-01  12

    SQL Server  (截至当前最新补丁版本2005 SP4, 2008 SP2), 存在一个非常隐蔽的语法问题:当子查询中不存在一个列名A, 但在外层查询中存在列名A,则语法不报错,返回不合理的结果。示例如下: 

    create table t_test1(col1 int);

    insert into t_test1 values(1);

     

    create table t_test2 (col1 int, col2 int);

    insert into t_test2 values(1, 10);

    insert into t_test2 values(2, 20);

    insert into t_test2 values(3, 30);

     

    select * from t_test2 where col2 in (select col2 from t_test1);

     -- 最后这个语句,不但未报错"找不到列col2", 而且返回来以下结果集

    col1        col2

    ----------- -----------

    1           10

    2           20

    3           30

    (3 行受影响)

     原因为: 命令解释进程先解释内层子查询"select col2 from t_test1",这时发现t_test1中没有col2这一列; 它然后再向外层查询寻求解释,恰好发现 外层的t_test2中,含有col2,结果导致它解释后的实际执行的命令,类似于这个语句执行的命令:select * from t_test2 as o where col2 in (select o.col2 from t_test1 as i);

     

    解决方法: 在子查询的列名前,指定表名(或伪名)。

    正确写法:select * from t_test2 where col2 in (select i.col2 from t_test1 as i);

     

    最新回复(0)