问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

ORACLE多表关联UPDATE语句

发布网友 发布时间:2023-03-29 00:36

我来回答

1个回答

热心网友 时间:2023-10-30 14:13

  为了方便起见 建立了以下简单模型 和构造了部分测试数据:

  在某个业务受理子系统BSS中

   客户资料表

  create table customers

  (

  customer_id   number( )    not null   客户标示

  city_name     varchar ( ) not null   所在城市

  customer_type char( )      not null   客户类型

  

  )

  create unique index PK_customers on customers (customer_id)

  由于某些原因 客户所在城市这个信息并不什么准确 但是在

  客户服务部的CRM子系统中 通过主动服务获取了部分客户 %的所在

  城市等准确信息 于是你将该部分信息提取至一张临时表中

  create table tmp_cust_city

  (

  customer_id     number( ) not null

  citye_name     varchar ( ) not null

  customer_type  char( )   not null

  )

   ) 最简单的形式

   经确认customers表中所有customer_id小于 均为 北京

   以内的均是公司走向全国之前的本城市的老客户:)

  update customers

  set    city_name= 北京

  where  customer_id<

   ) 两表(多表)关联update 仅在where字句中的连接

   这次提取的数据都是VIP 且包括新增的 所以顺便更新客户类别

  update customers   a       使用别名

  set    customer_type= 为vip 为普通

  where  exists (select

  from   tmp_cust_city b

  where  b customer_id=a customer_id

  )

   ) 两表(多表)关联update 被修改值由另一个表运算而来

  update customers a   使用别名

  set    city_name=(select b city_name from tmp_cust_city b where b customer_id=a customer_id)

  where  exists (select

  from   tmp_cust_city b

  where  b customer_id=a customer_id

  )

   update 超过 个值

  update customers a   使用别名

  set    (city_name customer_type)=(select b city_name b customer_type

  from   tmp_cust_city b

  where  b customer_id=a customer_id)

  where  exists (select

  from   tmp_cust_city b

  where  b customer_id=a customer_id

  )

  注意在这个语句中

  =(select b city_name b customer_type

  from   tmp_cust_city b

  where  b customer_id=a customer_id

  )

  与

  (select

  from   tmp_cust_city b

  where  b customer_id=a customer_id

  )

  是两个独立的子查询 查看执行计划可知 对b表/索引扫描了 篇

  如果舍弃where条件 则默认对A表进行全表

  更新 但由于(select b city_name from tmp_cust_city b where where  b customer_id=a customer_id)

  有可能不能提供 足够多 值 因为tmp_cust_city只是一部分客户的信息

  所以报错(如果指定的列 city_name可以为NULL则另当别论)

   cannot update (%s) to NULL

  // *Cause:

  // *Action:

  一个替代的方法可以采用

  update customers a   使用别名

  set    city_name=nvl((select b city_name from tmp_cust_city b where b customer_id=a customer_id) a city_name)

  或者

  set    city_name=nvl((select b city_name from tmp_cust_city b where b customer_id=a customer_id) 未知 )

   当然这不符合业务逻辑了

   ) 上述 )在一些情况下 因为B表的纪录只有A表的 %的纪录数

  考虑A表使用INDEX的情况 使用cursor也许会比关联update带来更好的性能

  set serveroutput on

  declare

  cursor city_cur is

  select customer_id city_name

  from   tmp_cust_city

  order by customer_id;

  begin

  for my_cur in city_cur loop

  update customers

  set    city_name=my_cur city_name

  where  customer_id=my_cur customer_id;

  /** 此处也可以单条/分批次提交 避免锁表情况 **/

        if mod(city_cur%rowcount )= then

            dbms_output put_line( );

            mit;

        end if;

  end loop;

  end;

   ) 关联update的一个特例以及性能再探讨

  在oracle的update语句语法中 除了可以update表之外 也可以是视图 所以有以下 个特例

  update (select a city_name b city_name as new_name

  from   customers a

  tmp_cust_city b

  where  b customer_id=a customer_id

  )

  set    city_name=new_name

  这样能避免对B表或其索引的 次扫描 但前提是 A(customer_id) b(customer_id)必需是unique index

  或primary key 否则报错

   cannot modify a column which maps to a non key preserved table

  // *Cause: An attempt was made to insert or update columns of a join view which

  //         map to a non key preserved table

  // *Action: Modify the underlying base tables directly

   )oracle另一个常见错误

  回到 )情况 由于某些原因 tmp_cust_city customer_id 不是唯一index/primary key

  update customers a   使用别名

  set    city_name=(select b city_name from tmp_cust_city b where b customer_id=a customer_id)

  where  exists (select

  from   tmp_cust_city b

  where  b customer_id=a customer_id

  )

  当对于一个给定的a customer_id

  (select b city_name from tmp_cust_city b where b customer_id=a customer_id)

  返回多余 条的情况 则会报如下错误

   single row subquery returns more than one row

  // *Cause:

  // *Action:

  一个比较简单近似于不负责任的做法是

  update customers a   使用别名

  set    city_name=(select b city_name from tmp_cust_city b where b customer_id=a customer_id and rownum= )

  如何理解 错误 在一个很复杂的多表连接update的语句 经常因考虑不周 出现这个错误

  仍已上述例子来描述 一个比较简便的方法就是将A表代入 值表达式 中 使用group by 和

  having 字句查看重复的纪录

  (select b customer_id b city_name count(*)

  from tmp_cust_city b customers a

  where b customer_id=a customer_id

  group by b customer_id b city_name

  having count(*)>=

lishixin/Article/program/Oracle/201311/18909
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
有要业余时间弹古筝的酒店么 古筝演奏师的就业前景怎么样 茶馆里主要放的音乐类型是 日语一级的话什么水平啊 一级到底要求多少词汇啊? WPS右键菜单(win11) 再生缘 我的温柔暴君结局是什么啊?女主最后傻了? 为什么做爱多了没感情了 情侣之间在一起时间长了是不是做爱的时候也懒得接吻了直接进入主题吗... 夫妻性爱后为何丧失了热情 《坠落过程》作者吴万夫简介? 安卓手机 软件占用运存如何查看 ?是设置--应用管理--正在运行 里面显示的准确,还是用36 小学三年级消防安全黑板报 小学三年级黑板报图片大全 消防黑板报图片大全? 2022全国消防宣传日特别节目观后感 晒黑的补救方法 如何补救晒黑 来自泰国的消息说微粒贷已给我开通78000额度,我没开通这个呀,这有啥坏处吗? 梦见家里飞来一只鸡的预兆 京东保障服务可以退了吗 5分钟开学典礼教师发言稿 开学典礼优秀班级教师发言稿 数学切胡萝卜切面,用什么上色 只有护照复印件怎么办签证 微信的朋友圈里,别人发的视频,我想转发到朋友圈,为什么转发不了? 知道微信密码自己会被盗吗?或者偷钱啥的 随着天气转暖气温回升,鱼的活性变高,原本消停的小杂鱼,又开始闹腾了吗? 梦到抓了很多杂鱼还有美女 梦见好多杂鱼的预兆 用什么软件可以复制被锁的文字? 侄女大学挂科太多被学校劝退怎么办?能不能不退?有什么好办法?急求上策! 哪些药物会造成身体发胖 醋酸甲羟孕酮片是激素药吗会发胖吗 吃了地屈孕酮片会发胖,地屈孕酮片一般吃几天 芬吗通雌二醇地屈孕酮片吃了会发胖吗,地屈孕酮片和优思明的区别 影响一生的经典短句 影响一生的名言 影响一生的经典励志语录感悟,句句正能量! 热敏炉和电陶炉的区别 为什么我的电脑看优酷视频时缓冲到一半就缓冲不了,停止不动,我网络没有问题 谈理想的中学生演讲稿 按此格式,在科目汇总表里编辑EXCEL公式,让每月合计数自动生成,而不改变科目汇总表里的公式? 如何在EXCEL中设计好格式,自动汇总“科目汇总表”? 求谁会制作自动求和的科目汇总表的表格或者是方法,知道的请发个QQ1056641120,谢谢啦! 用excel制作会计凭证后自动生成科目汇总表、负债表、现金流量表、利润表,能自动汇总的, 求用excel制作会计凭证、科目汇总表、负债表、利润表、能自动汇总的 医保的种类与缴费时间 联想cs1831w打印机费耗材 联想打印机M3120的墨盒怎么换? 求:世界上最罕见的绝症以及其的症状 五大绝症是什么?