首页 > 解决方案 > Oracle:需要在相关更新中存在

问题描述

我正在通过以下链接进行 SQL 练习 https://oracle-base.com/articles/misc/updates-based-on-queries

在子查询方法中,代码如下

UPDATE dest_tab tt
SET    (tt.code, tt.description) = (SELECT st.code, st.description
                                    FROM   source_tab st
                                    WHERE  st.id = tt.id)
WHERE  EXISTS (SELECT 1
               FROM   source_tab
               WHERE  id = tt.id);

我可以理解使用连接的相关部分,但是 EXISTS 运算符的用途是什么。根据文章,它应该在更新目标表时排除不匹配的记录。但是那应该通过加入条件来处理,对吧?那只是在源和目标之间具有匹配 id 的记录。这是因为 WHERE 子句是强制性的,以避免更新整个表,即使我们在源和目标之间有一个等连接?

标签: oracleexists

解决方案


如果没有exists,您将更新dest_tab. 因此,如果有任何行 indest_tab中没有匹配的行source_tab,它们的列将设置为 null:

create table t1 (
  c1 int, c2 int
);

create table t2 (
  c1 int, c2 int
);


insert into t1 values ( 1, 1 );
insert into t1 values ( 2, 2 );

insert into t2 values ( 1, 999 );

commit;

update t1
set    c2 = ( 
  select c2 from t2
  where  t1.c1 = t2.c1
);

select * from t1;

C1     C2       
    1       999 
    2    <null> 

添加该exists子句可避免此问题:

rollback;

update t1
set    c2 = ( 
  select c2 from t2
  where  t1.c1 = t2.c1
)
where  exists (
  select null from t2
  where  t1.c1 = t2.c1
);

select * from t1;

C1    C2    
    1    999 
    2      2 

推荐阅读