oracle - 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 子句是强制性的,以避免更新整个表,即使我们在源和目标之间有一个等连接?
解决方案
如果没有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
推荐阅读
- jsf - p:selectOneMenu 的自定义验证器使其无法渲染/无法渲染其他组件
- python - 在 matplotlib/pyplot 的散点图中缩进代码行的问题
- xcode - Xcode View - 尝试将结构的名称(var)显示为文本
- spartacus-storefront - 在 Spartacus 中配置会话超时的位置
- android - 在 Android Studio 上的 Fragment 中扫描 BLE 设备 - Kotlin
- spring-boot - 为什么从springboot中的application.yml文件读取属性的类中的字段必须设置setter?
- postgresql - 在仍然看到其他列的同时找到特定列的最大值
- c# - 对于任何方法,如何只允许大于零的参数值?
- c - 使用 Clang 将文件编译为静态二进制文件时出错
- c++ - 在我的程序中出现错误:“分段错误(核心转储)”。一切正常。为什么?