资讯动态

Oracle - 两表关联更新

发布时间:2026/10/24 1:40:40 来源:尧图企业网站定制
方法一MERGE INTOMERGE INTO语法主要用于在数据库中根据匹配条件更新数据适用于需要同时查询A表和B表才能确定更新数据的情况MERGEINTOTAB1 AUSINGTAB2 BON(A.G_SGMT_IDB.G_SGMT_IDANDA.GEAR_THR_REF_NOB.REF_NOANDA.G_TRSC_AMTB.G_CABL_FEEANDA.CAN_DV_CD2ANDA.TRSC_DT20241118)WHENMATCHEDTHENUPDATESETA.TRSC_MEMO_CTT测试;这条语句是一个SQL的MERGE语句用于将TAB2表中的数据合并到TAB1表中。MERGE语句是一种非常强大的工具它允许你根据一定的匹配条件来更新目标表中的数据或者在匹配失败时插入新的数据虽然在这个特定的例子中并没有包含插入操作。下面是对这条语句的详细分析目标表TAB1和源表TAB2MERGE INTO TAB1 A指定TAB1为目标表并给它一个别名A。USING TAB2 B指定TAB2为源表并给它一个别名B。匹配条件ON (A.G_SGMT_ID B.G_SGMT_ID AND A.GEAR_THR_REF_NO B.REF_NO AND A.G_TRSC_AMT B.G_CABL_FEE AND A.CAN_DV_CD 2 AND A.TRSC_DT 20241118)这些条件用于确定TAB1和TAB2中的哪些行应该被视为匹配。A.G_SGMT_ID B.G_SGMT_ID要求两个表中的G_SGMT_ID字段值相同。A.GEAR_THR_REF_NO B.REF_NO要求TAB1的GEAR_THR_REF_NO字段值与TAB2的REF_NO字段值相同。A.G_TRSC_AMT B.G_CABL_FEE要求两个表中的字段值相同。A.TRSC_DT 20241118要求TAB1中的TRSC_DT交易日期字段值大于或等于20241118。操作WHEN MATCHED THEN UPDATE SET A.TRSC_MEMO_CTT 测试;当找到匹配的行时执行更新操作。将TAB1表中匹配行的TRSC_MEMO_CTT字段更新为测试。注意这个MERGE语句只包含了更新操作。如果需要在没有匹配项时插入新数据可以添加WHEN NOT MATCHED THEN INSERT子句。方法二EXISTSUPDATE需要更新的表名 BSETB.更新字段1更新内容1,B.更新字段2更新内容2WHEREEXISTS(SELECT1FROM关联表名 AWHEREA.关联字段B.关联字段ANDA.筛选字段1筛选字段1ANDA.筛选字段2筛选字段2ANDB.筛选字段3筛选字段3);问题分析需要写一个更新语句但是更新的判断条件是两个表关联查询出来的踩坑一一开始是打算UPDATE写两个表然后WHERE里面两表关联就像这样:--错误sqlUPDATE表名1A,表名2BSETA.更新字段1更新内容1,A.更新字段2更新内容2WHEREA.关联字段B.关联字段ANDA.筛选字段1筛选字段1ANDA.筛选字段2筛选字段2ANDB.筛选字段3筛选字段3但是一直报错很明显也不是缺失SET 关键字的问题踩坑二之后搜索怎么在Oracel关联两表更新。发现了下面这种写法--正常sqlUPDATE更新表名 ASETA.更新字段1更新内容1WHEREEXISTS(SELECT1FROM关联表名 BWHEREA.关联字段B.关联字段)但是也是没太仔细看加上思维固化写成了下面这种情况--错误sqlUPDATE更新表名 ASETA.更新字段1更新内容1WHEREEXISTS(SELECT1FROM更新表名 A,关联表名 BWHEREA.关联字段B.关联字段ANDA.筛选字段1筛选字段1)可以看到在FROM里面比搜索出来的sql语句多了更新的表名A显而易见还会有点问题但是这次并不是报错而是筛选不是自己预想的筛选导致更新的数据非常多像下图一样更新语句跑了1分半更新了46万条数据。。。明显是有问题的实际上只需要更新几十条被更新的B表实际上也只有26万条数据不知道46万条更新怎么来的只能先回滚更新通过对比发现是FROM多写了个更新的表名修改之后可以正常的更新没有问题踩坑三既然已经可以两表关联查询更新其中一个表了那能不能同时更新两个表呢想当然的认为sql应该是这样的UPDATE更新表1ASETA.更新字段1A表更新内容1,B.更新字段2B表更新内容2WHEREEXISTS(SELECT1FROM更新表2BWHEREA.关联字段B.关联字段ANDA.筛选字段筛选字段)于是写出了下面的sql但是事实证明这样写是不行的语句分析UPDATE需要更新的表名 BSETB.更新字段1更新内容1,B.更新字段2更新内容2WHEREEXISTS(SELECT1FROM关联表名 AWHEREA.关联字段B.关联字段ANDA.筛选字段1筛选字段1ANDA.筛选字段2筛选字段2ANDB.筛选字段3筛选字段3);A表和B表都有相同的关联字段并且通过筛选字段校验。那么就有SELECT 1那么EXISTS就会返回TRUE最后进行更新操作。EXISTSEXISTS用于检查子查询是否至少会返回一行数据该子查询实际上并不返回任何数据而是返回值True或FalseEXISTS(包括 NOT EXISTS )子句的返回值是一个BOOL值。 EXISTS内部有一个子查询语句(SELECT … FROM…) 我将其称为EXISTS的内查询语句。其内查询语句返回一个结果集。 EXISTS子句根据其内查询语句的结果集空或者非空返回一个布尔值。此时在该更新sql中--EXISTS的内查询语句为SELECT1FROM关联表名 AWHEREA.关联字段B.关联字段ANDA.筛选字段1筛选字段1ANDA.筛选字段2筛选字段2ANDB.筛选字段3筛选字段3--WHERE判断EXISTS返回的BOOL值来决定是否更新WHEREEXISTSSELECT 1当我们只关心数据表有多少记录行而不需要知道具体的字段值时SELECT 1 FROM TABLE是一个很不错的SQL语句写法它通常用于子查询。SELECT 1 FROM TABLE可以减少系统开销提高运行效率。因为此时数据库就不会去检索数据表里每条具体的记录和每条记录里每个具体的字段值并将它们放到内存里而是查询到有多少记录行存在就输出多少个“1”每个“1”代表有1行记录。选用数字1是因为它所占用的内存空间最小用数字0的效果也一样即SELECT 0 FROM TABLE。从效率上来说SELECT 1 SELECT 字段 SELECT *在子查询中的应用常规写法SELECT*FROMt1 aWHEREEXISTS(SELECT*FROMt2 bWHEREa.idb.id)更优写法SELECT*FROMt1 aWHEREEXISTS(SELECT1FROMt2 bWHEREa.idb.id)

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑