程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle教程 >> ORACLE 關連更新 update select,oracleupdate

ORACLE 關連更新 update select,oracleupdate

編輯:Oracle教程

ORACLE 關連更新 update select,oracleupdate


 

總結:  關鍵的地方是where 語句的加入. 在11G中, 如果不加11G , 或造成除匹配的行數更新為相應的值之後, 其余的會變成負數. 

    所以, 測試的辦法就是:  先查看需要更新的數量即連接的數量究竟有多少行, 然後update 之後多少行, 才能確定條件是否正確.

 

引入知識比較全面的地址: 

 

http://www.blogjava.net/Jhonney/archive/2010/06/25/324503.html.  文章最後注明轉載.

 

本人用到的2處SQL:

1 :   

  1. UPDATE SFISM4.R_DT_DIP_TRACEABILITY_T B
  2. SET (B.CURRENT_QTY, B.UPDATE_TIME, B.UPDATE_USER)=
  3. (SELECT DECODE(SIGN(B.CURRENT_QTY - A.KP_COUNT),
  4. -1,
  5. 0,
  6. B.CURRENT_QTY - A.KP_COUNT),
  7. SYSDATE,
  8. :VUSER
  9. FROM SFIS1.C_DT_DIP_BOM_T A, SFISM4.R_MO_BASE_T C
  10. WHERE A.BOM_NO = B.BOM_NO
  11. AND B.BOM_NO = C.KEY_PART_NO
  12. AND A.KEY_PART_NO = B.KEY_PART_NO
  13. AND C.MO_NUMBER =:VBOM
  14. AND B.TRAC_LOT =:VTRACELOT)
  15. WHERE B.TRAC_LOT =:VTRACELOT
  16. AND EXISTS (SELECT 1
  17. FROM SFIS1.C_DT_DIP_BOM_T AA
  18. WHERE B.BOM_NO = AA.BOM_NO
  19. AND B.KEY_PART_NO = AA.KEY_PART_NO)
  20. UPDATE SFISM4.R_REEL_TRACKING_T A
  21. SET A.REMAIN_QTY =
  22. (SELECT B.REEL_QTY
  23. FROM SFISM4.R_MMS_STOCK_SMT_SA_DETAIL_T B
  24. WHERE A.REEL_ID = B.REEL_ID
  25. AND A.REMAIN_QTY <0
  26. AND A.REMAIN_QTY <> B.REEL_QTY)
  27. WHERE EXISTS (SELECT 1
  28. FROM SFISM4.R_MMS_STOCK_SMT_SA_DETAIL_T B
  29. WHERE A.REEL_ID = B.REEL_ID
  30. AND A.REMAIN_QTY <0
  31. AND A.REMAIN_QTY <> B.REEL_QTY);
  2: 
  1. UPDATE SFISM4.R_REEL_TRACKING_T A
  2. SET A.REMAIN_QTY =
  3. (SELECT B.REEL_QTY
  4. FROM SFISM4.R_MMS_STOCK_SMT_SA_DETAIL_T B
  5. WHERE A.REEL_ID = B.REEL_ID
  6. AND A.REMAIN_QTY <0
  7. AND A.REMAIN_QTY <> B.REEL_QTY)
  8. WHERE EXISTS (SELECT 1
  9. FROM SFISM4.R_MMS_STOCK_SMT_SA_DETAIL_T B
  10. WHERE A.REEL_ID = B.REEL_ID
  11. AND A.REMAIN_QTY <0
  12. AND A.REMAIN_QTY <> B.REEL_QTY);
  最後是引用比較好的說明如下, 進行標注: 原文網址: http://www.blogjava.net/Jhonney/archive/2010/06/25/324503.html  

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條數據就是正確的. 這一步是驗證更新是不是對, 錯的關鍵.!!! 相信程序員是通過以下類似的SQL更新的,這是錯誤的,因為沒有加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的相關用法.
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) -- 表連接之後, 更新視圖的方式很好理解. 但是需要primary key.
  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 這個方法是最靈活的了. 方法五: 注意,方法五只能適用於WWM5是WWM2的子集的時候. (新特性 merge Into,哎呀! 不想學.....)
  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
-------------------- ----------
                                  ---注意這個地方,被插入了一個空值.因為WWM5的ID=9984在WWM2中不能匹配,根本原因是ORACLE9必須有WHEN NOT MATCHED子句,但是ORACLE10可以不許要,也就是ORACLE10可以不寫WHEN NOT MATCHED ,就不必插入NULL值了,為解決這個問題,下一步會DELETE WWM5的ID=9984,這樣一來就不會執行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種關連更新的例子了,希望能給開發人員解惑.   說明:如果select 子句可以返回多行記錄,但返回適合where條件的記錄只能是唯一的,否則將會報返回單行的select子句返回多行的錯誤,因為update只能跟據此處的where子句(內層where)進行相應記錄的匹配更新,一次只能是一條。     



來自為知筆記(Wiz)



  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved