oracle多表關聯更新


oracle的更新語句不通MSSQL那么簡單易寫,就算寫出來了,但執行時可能會報 這是由於set哪里的子查詢查出了多行數據值,oracle規定一對一更新數據,所以提示出錯。要解決這樣必須保證查出來的值一一對應。

原理 Update語句的原理是先根據where條件查到數據后,如果set中有子查詢,則執行子查詢把值查出來賦給更新的字段,執行更新。

update dept a
    set a.loc = (select b.loc from test_dept b where a.deptno = b.deptno)
  where exists (select 1 from test_dept b where a.deptno = b.deptno);

查表a的所有數據,循環每條數據,驗證該條數據是否符合exists(select 1 from 表b where a.字段2=b.字段2)條件,如果是則執行(select b.字段1 from 表b where a.字段2=b.字段2)查詢,查到對應的值更新a.字段1中。關聯表更新時一定要有exists(select 1 from 表b where a.字段2=b.字段2)這樣的條件,否則將表a的其他數據的字段1更新為null值。

二、提高oracle更新效率的各種解決方案

1,標准update語法 當需要更新的表是單個或者被更新的字段不需要關聯其他表帶過來,則最后選擇標准的update語句,速度最快,穩定性最好,並返回影響條數。 如果where條件中的字段加上索引,那么更新效率就更高。但對需要關聯表更新字段時,update的效率就非常差。

2,inline view更新法 inline view更新法就是更新一個臨時建立的視圖。如:

 代碼示例:

update (select a.join_state as join_state_a, b.join_state as join_state_b
          from t_join_situation a, t_people_info b
         where a.people_number = b.people_number
           and a.year = '2011'
           and a.city_number = 'M00000'
           and a.town_number = 'M51000')
   set join_state_a = join_state_b

  括號里通過關聯兩表建立一個視圖,set中設置好更新的字段。這個解決方法比寫法較直觀且執行速度快。但表B的主鍵一定要在where條件中,並且是以“=”來關聯被更新表,否則報一下錯誤:   3,merge更新法 merge是oracle特有的語句,語法如下:  

 

 代碼示例:

MERGE INTO table_name alias1
USING (table | view | sub_query) alias2
ON (join condition)
WHEN MATCHED THEN
  UPDATE table_name SET col1 = col_val1, col2 = col2_val
WHEN NOT MATCHED THEN
  INSERT (column_list) VALUES (column_values);

原理分析:在alias2中Select出來的數據,每一條都跟alias1進行 ON (join condition)的比較,如果匹配,就進行更新的操作(Update),如果不匹配,就進行插入操作(Insert)。執行merge不會返回影響的行數。Merge語句的寫法比較繁瑣,並且最多只能兩個表關聯,復雜的語句用merge更新法將力不從心且效率差。

4,快速游標更新法 語法如:  

begin for cr in (查詢語句) loop –-循環    --更新語句(根據查詢出來的結果集合) endloop; --結束循環 end;   oracle支持快速游標,不需要定義直接把游標寫到for循環中,這樣就方便了我們批量更新數據。再加上oracle的rowid物理字段(oracle默認給每個表都有rowid這個字段,並且是唯一索引),可以快速定位到要更新的記錄上。

例子:  

代碼示例:


begin
for cr in (select a.rowid,b.join_state
             from t_join_situation a,t_people_info b
            where a.people_number=b.people_number and
                  a.year='2011'and
                  a.city_number='M00000'and
                  a.town_number='M51000'
           )
loop
  update t_join_situation set join_state=cr.join_state where
  rowid = cr.rowid;
end loop;
end;

  使用快速游標的好處很多,可以支持復雜的查詢語句,更新准確,無論數據多大更新效率仍然高,但執行后不返回影響行數。

三、結論 方案 建議 標准update語法 單表更新或較簡單的語句采用使用此方案更優。 inline view更新法 兩表關聯且被更新表通過關聯表主鍵關聯的,采用此方案更優。 merge更新法 兩表關聯且被更新表不是通過關聯表主鍵關聯的,采用此方案更優。 快速游標更新法 多表關聯且邏輯復雜的,采用此方案更優。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM