Jhonney的專(zhuān)欄

             ----人見(jiàn)人愛(ài)
          隨筆 - 49, 文章 - 1, 評(píng)論 - 23, 引用 - 0
          數(shù)據(jù)加載中……

          ORACLE 關(guān)連更新 update select

          $ sqlplus user/pass

          SQL*Plus: Release 9.2.0.6.0 - Production on Wed Aug 2 17:38:39 2006

          Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.


          Connected to:
          Oracle9i Enterprise Edition Release 9.2.0.6.0 - 64bit Production
          With the Partitioning, OLAP and Oracle Data Mining options
          JServer Release 9.2.0.6.0 - Production

          SQL> select * from wwm2;        --要更新的表

          TOWN                         ID
          -------------------- ----------
          222                         222
          111                         111
          ww'jj                       111
          llll                       1111
          dddd                       2222
          lllldf                      111
          lllldf                      111
          dsafdf                      111
          3435                        111
          ljjjjj                      222
          dsafdf                      111
          TOWN                         ID
          -------------------- ----------
          3435                        111
          ljjjjj                      222

          SQL> select * from wwm5;            --更新的條件表
          TOWN                         ID
          -------------------- ----------
          lllldf                      111
          test                       9984
          SQL> select wwm2.* from wwm2,wwm5 where wwm2.id=wwm5.id
            2  /
          TOWN                         ID
          -------------------- ----------
          111                         111
          ww'jj                       111
          lllldf                      111
          lllldf                      111
          dsafdf                      111
          3435                        111
          dsafdf                      111
          3435                        111
          8 rows selected.
          所以,每次需要更新8條數(shù)據(jù)就是正確的.
          相信程序員是通過(guò)以下類(lèi)似的SQL更新的,這是錯(cuò)誤的,因?yàn)闆](méi)有加WHERE
          SQL>  update wwm2 set wwm2.town=(select wwm5.town from wwm5 where wwm5.id=wwm2.id)
            2  /
          13 rows updated.
          SQL> select * from wwm2;
          TOWN                         ID
          -------------------- ----------
                                      222
          lllldf                      111
          lllldf                      111
                                     1111
                                     2222
          lllldf                      111
          lllldf                      111
          lllldf                      111
          lllldf                      111
                                      222
          lllldf                      111
          TOWN                         ID
          -------------------- ----------
          lllldf                      111
                                      222
          13 rows selected.
          可以看到13條記錄被更新,符合條件的更新正確,不符合條件的也更新為NULL.以下是正確的方法
          方法一:
          SQL> update wwm2
            2  set town=(select town from wwm5 where wwm5.id=wwm2.id)
            3  where id=(select wwm5.id from wwm5 where wwm5.id=wwm2.id)
            4  /
          8 rows updated.
          方法二:    與方法一道理相同,這里需要掌握EXIST的相關(guān)用法.
          SQL> update wwm2
             set town=(select town from wwm5 where wwm5.id=wwm2.id)
             where exists (select 1 from wwm5 where wwm5.id=wwm2.id)
          8 rows updated.
          方法三:
          SQL> update (select a.town atown,a.id aid,b.town btown,b.id bid from wwm2 a,wwm5 b where a.id=b.id)
            2  set atown=btown
            3  /
          set atown=btown
              *
          ERROR at line 2:
          ORA-01779: cannot modify a column which maps to a non key-preserved table
            1* alter table wwm5 add primary key (id)
          SQL> /
          Table altered.
            1  update (select a.town atown,a.id aid,b.town btown,b.id bid from wwm2 a,wwm5 b where a.id=b.id)
            2*  set atown=btown
          SQL> /
          8 rows updated.
          這種方法的局限性就是需要PRIMARY 的支持.
          方法四:
            1  declare
            2  cursor cur_wwm is select town,id from wwm5;
            3  begin
            4     for my_wwm in cur_wwm loop
            5     update wwm2 set town=my_wwm.town
            6     where id=my_wwm.id;
            7     end loop;
            8* end;
          SQL> /
          PL/SQL procedure successfully completed.
          SQL> select * from wwm2;
          TOWN                         ID
          -------------------- ----------
          222                         222
          lllldf                      111
          lllldf                      111
          llll                       1111
          dddd                       2222
          lllldf                      111
          lllldf                      111
          lllldf                      111
          lllldf                      111
          ljjjjj                      222
          lllldf                      111
          TOWN                         ID
          -------------------- ----------
          lllldf                      111
          ljjjjj                      222
          這個(gè)方法是最靈活的了.
          方法五:
          注意,方法五只能適用于WWM5是WWM2的子集的時(shí)候.
            1   merge into wwm2
            2   using (select town,id from wwm5) b
            3   on (wwm2.id=b.id)
            4   when matched then update set town=b.town
            5* when not matched then insert (town,id) values (null,null)
          SQL> /
          9 rows merged.
          SQL> select * from wwm2;
          TOWN                         ID
          -------------------- ----------
                                            ---注意這個(gè)地方,被插入了一個(gè)空值.因?yàn)閃WM5的ID=9984在WWM2中不能匹配,根本原因是ORACLE9必須有WHEN NOT MATCHED子句,但是ORACLE10可以不許要,也就是ORACLE10可以不寫(xiě)WHEN NOT MATCHED ,就不必插入NULL值了,為解決這個(gè)問(wèn)題,下一步會(huì)DELETE WWM5的ID=9984,這樣一來(lái)就不會(huì)執(zhí)行WHEN NOT MATCHED
          222                         222
          lllldf                      111
          lllldf                      111
          llll                       1111
          dddd                       2222
          lllldf                      111
          lllldf                      111
          lllldf                      111
          lllldf                      111
          ljjjjj                      222
          TOWN                         ID
          -------------------- ----------
          lllldf                      111
          lllldf                      111
          ljjjjj                      222
          14 rows selected.
          SQL> delete from wwm5 where id=9984;
          1 row deleted.
          SQL>  1   merge into wwm2                            
          SQL>   2   using (select town,id from wwm5) b
          SQL>   3   on (wwm2.id=b.id)
          SQL>   4   when matched then update set town=b.town
          SQL>   5* when not matched then insert (town,id) values (null,null)
          SQL> /
          8 rows merged.
           
                 以上就是5種關(guān)連更新的例子了,希望能給開(kāi)發(fā)人員解惑.
           
          說(shuō)明:如果select 子句可以返回多行記錄,但返回適合where條件的記錄只能是唯一的,否則將會(huì)報(bào)返回單行的select子句返回多行的錯(cuò)誤,因?yàn)閡pdate只能跟據(jù)此處的where子句(內(nèi)層where)進(jìn)行相應(yīng)記錄的匹配更新,一次只能是一條。

          posted on 2010-06-25 19:30 Jhonney 閱讀(17204) 評(píng)論(0)  編輯  收藏


          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 长春市| 中山市| 任丘市| 汉寿县| 镇康县| 新蔡县| 南丹县| 翁源县| 汽车| 龙海市| 游戏| 盐山县| 启东市| 焦作市| 大竹县| 沙田区| 常熟市| 信丰县| 东山县| 临武县| 遂平县| 山东省| 安远县| 宁化县| 陈巴尔虎旗| 吉首市| 温州市| 南汇区| 建平县| 静乐县| 达孜县| 济源市| 辛集市| 昭平县| 阳高县| 广德县| 凤翔县| 沈阳市| 闸北区| 莆田市| 武宣县|