更新语句使用子查询给出错误的结果

时间:2019-01-03 11:22:38

标签: sql sql-server oracle sql-update in-subquery

我有以下查询,当我在子查询中使用不存在的列引用时,该查询没有错误。我在子查询中引用的列实际上是要更新的表中的列。

create table tbl1 (f1 bigint, f2 char(10), f3 integer);
insert into tbl1 values (1, 'aa', 0);
insert into tbl1 values (2, 'bb', 0);
insert into tbl1 values (3, 'cc', 0);
insert into tbl1 values (4, 'dd', 0);

create table temp_tbl (ref_num bigint);
insert into temp_tbl values (1);
insert into temp_tbl values (3);

update tbl1 set f2='ok' where f1 in (select f1 from temp_tbl);
-- 4 records updated

谁能告诉我为什么它没有给出任何错误?且记录会根据情况进行更新。

  

我在Oracle和SQLserver中都尝试过。结果是一样的

2 个答案:

答案 0 :(得分:0)

之所以发生这种情况,是因为SELECT中的值不必只是要从中选择的表中的列,子查询从外部查询中返回f1的值,而不是temp_tbl中的值。

考虑是否将UPDATE查询重写为:

SELECT  *
FROM    tbl1 
WHERE   f1 IN (select f1 from temp_tbl);

返回的结果实际上是:

The results of executing the query

当您试图对诸如此类的事情进行推理时(这是正确完成查询的一种很好的方法!),将您的UPDATE查询写成以下形式很有用:

UPDATE  T
SET     F2 = 'ok'
FROM    TBL1 T
WHERE   T.f1 IN
        (
            SELECT  F1
            FROM    temp_tbl
        )

通过这种方式编写,您可以轻松注释掉查询的UPDATESET组件,将它们替换为SELECT并查看查询将要处理的数据集在。

答案 1 :(得分:0)

子查询的列引用转到外部表!

update tbl1 set f2='ok' where f1 in (select f1 from temp_tbl);

读为

update tbl1 set f2='ok' where f1 in (select tbl1.f1 from temp_tbl);

限定您的列:

update tbl1 set f2='ok' where f1 in (select temp_tbl.ref_num  from temp_tbl);