oracle面试题解析(用一条sql语句实现批量一对一更新)

需求:现在有一个项目表project,里面的字段主要有proj_Id,money,主键字段为id,proj_Id可能为空,money字段类型为NUMBER(17,2),
在某种条件下,会关联表proj_appl表字段proj_Id,
另外一个表proj_appl,里面的字段主要有proj_Id,appl_money,主键字段为proj_Id,appl_money字段类型为NUMBER(17,2),
现在两边的金额不一致,需要把两个表金额不一致的替换为金额一致的表,金额以表proj_appl表字段proj_Id为准。

如何利用一条sql语句实现?

分析:
首先我想到的是先通过两张表的关联关系,查询出项目proj_Id,然后根据proj_Id去进行依次更新,因为最开始
我想的是不能做批量更新,只能一个一个的去更新,所以第一步我的实现方式用到了游标,具体sql如下:

declare cursor cur_node is
select p.proj_Id
from project t,proj_appl p
where t.proj_Id = p.proj_Id
and t.money <> p.appl_money
and t.proj_Id is not null;

begin
for node is cur_node loop

update project m
set m.money= (select p.appl_money from proj_appl p where p.proj_Id=node.proj_Id)
where m.proj_Id = node.proj_Id;

end loop;

END;
/
commit;

仔细看这个sql感觉没什么问题,也可以实现需求,但是仔细思考,还是发现了问题。
如果这两张的数据量比较大,这样去更新似乎没什么问题。但是如果这两张表的数据量比较小,
都只有几万条数据量,那么,这个sql就不是最简单的,最简单的sql如下:

update project m
set m.money= (select p.appl_money from proj_appl p
where p.proj_Id=m.proj_Id
and m.money <> p.appl_money
)
where m.proj_Id is not null;

commit;

仔细看这个sql感觉也没有什么问题,但是上到测试环境去之后才发现,
这个sql会把project表里面的money字段原本跟proj_appl表里面的appl_money字段相等的金额
置为null,换言之,这个sql会把表project原本和proj_appl相等的金额字段更新为null,
这个没有达到用户的原始需求。

经过不断地尝试,最后调整sql如下:

update project m
set m.money= nvl((select p.appl_money from proj_appl p
where p.proj_Id=m.proj_Id
),m.money)
where m.proj_Id is not null;

commit;

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值