ORACLE 多表关联 UPDATE 语句_第1页
ORACLE 多表关联 UPDATE 语句_第2页
ORACLE 多表关联 UPDATE 语句_第3页
ORACLE 多表关联 UPDATE 语句_第4页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

ORACLE多表关联UPDATE语句为了方便起见,建立了以下简单模型,和构造了部分测试数据:在某个业务受理子系统BSS中,--客户资料表createtablecustomers(customer_idnumber(8) not null, -- 客户标示city_namevarchar2(10) not null, -- 所在城市customer_typechar(2) not null, -- 客户类型)createuniqueindexPK_customersoncustomers(customer_id)由于某些原因,客户所在城市这个信息并不什么准确,但是在客户服务部的CRM子系统中,通过主动服务获取了部分客户20%的所在城市等准确信息,于是你将该部分信息提取至一张临时表中:createtabletmp_cust_city(customer_id number(8)notnull,citye_name varchar2(10)notnull,customer_typechar(2)notnull)最简单的形式--经确认customers表中所有customer_id小于1000均为'北京'--1000以内的均是公司走向全国之前的本城市的老客户:)updatecustomersset city_name二北京’wherecustomer_id<1000两表(多表)关联update—仅在where字句中的连接—这次提取的数据都是VIP,且包括新增的,所以顺便更新客户类别updatecustomersa --使用别名setcustomer_type='01'--01为vip,00为普通whereexists(select1fromtmp_cust_citybwhereb.customer_id=a.customer_id)两表(多表)关联update—被修改值由另一个表运算而来updatecustomersa--使用别名wheresetcity_name=(selectb.city_namefromtmp_cust_citybb.customer_id=a.customer_id)wherewhereexists(select1fromtmp_cust_citybwhereb.customer_id=a.customer_id)--update超过2个值updatecustomersa--使用别名set(city_name,customer_type)=(selectb.city_name,b.customer_typefromtmp_cust_citybwhereb.customer_id=a.customer_id)whereexists(select1fromtmp_cust_citybwhereb.customer_id=a.customer_id)注意在这个语句中,=(selectb.city_name,b.customer_typefromtmp_cust_citybwhereb.customer_id=a.customer_id)与(select1fromtmp_cust_citybwhereb.customer_id=a.customer_id)是两个独立的子查询,查看执行计划可知,对b表/索引扫描了2篇;如果舍弃where条件,则默认对A表进行全表更新,但由于(selectb.city_namefromtmp_cust_citybwherewhereb.customer_id=a.customer_id)有可能不能提供"足够多"值,因为tmp_cust_city只是一部分客户的信息,所以报错(如果指定的列--city_name可以为NULL则另当别论):01407,00000,"cannotupdate(%s)toNULL"//*Cause://*Action:一个替代的方法可以采用:updatecustomersa--使用别名setcity_name=nvl((selectb.city_namefromtmp_cust_citybwhereb.customer_id=a.customer_id),a.city_name)或者setcity_name=nvl((selectb.city_namefromtmp_cust_citybwhereb.customer_id二a.customer_id),'未知')--当然这不符合业务逻辑了上述3)在一些情况下,因为B表的纪录只有A表的20-30%的纪录数,考虑A表使用INDEX的情况,使用cursor也许会比关联update带来更好的性能:setserveroutputondeclarecursorcity_curisselectcustomer_id,city_namefromtmp_cust_cityorderbycustomer_id;beginformy_curincity_curloopupdatecustomerssetcity_name=my_cur.city_namewherecustomer_id=my_cur.customer_id;/**此处也可以单条/分批次提交,避免锁表情况**/-- ifmod(city_cur%rowcount,10000)=0then-- dbms_output.put_line(' ');-- commit;-- endif;endloop;end;关联update的一个特例以及性能再探讨在oracle的update语句语法中,除了可以update表之外,也可以是视图,所以有以下1个特例:update(selecta.city_name,b.city_nameasnew_namefromcustomersa,tmp_cust_citybwhereb.customer_id=a.customer_id)setcity_name=new_name这样能避免对B表或其索引的2次扫描,但前提是A(customer_id)b(customer_id)必需是uniqueindex或primarykey。否则报错:01779,00000,"cannotmodifyacolumnwhichmapstoanonkey-preservedtable"//*Cause:Anattemptwasmadetoinsertorupdatecolumnsofajoinviewwhich//maptoanon-key-preservedtable.//*Action:Modifytheunderlyingbasetablesdirectly.oracle另一个常见错误回到3)情况,由于某些原因,tmp_cust_citycustomer_id不是唯一index/primarykeyupdatecustomersa--使用别名setcity_name=(selectb.city_namefromtmp_cust_citybwhereb.customer_id=a.customer_id)whereexists(select1fromtmp_cust_citybwhereb.customer_id=a.customer_id)当对于一个给定的a.customer_id(selectb.city_namefromtmp_cust_citybwhereb.customer_id=a.customer_id)返回多余1条的情况,则会报如下错误:01427,00000,"single-rowsubqueryreturnsmorethanonerow"//*Cause://*Action:一个比较简单近似于不负责任的做法是updatecustomersa--使用别名setcity_name=(selectb.city_namefromtmp_cust_citybwhereb.customer_id=a.customer_idandrownum=1)如何理解01427错误,在一个很复杂的多表连接update的语句,经常因考虑不周,出现这个错误,仍已上述例子来描述,一个比较简便的方

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论