2015-09-21 33 views
0

我現在使用merge into聲明,但它不符合要求。目前這樣的代碼......Oracle 11g - 如何在合併語句中執行多行?

create or replace procedure 
    mv_data 
is 
begin 
    merge into WORK w 
    using (select * from IF_WORK where batch = 0) i 
     on (w.token in (select token from IF_WORK where batch = 0)) 
    when matched then 
     update set 
     w.area = i.area 
     , w.cust_id = i.cust_id 
     , w.status = i.status 
     , w.changed = sysdate 
     where w.token = i.token 
     -- I want to put "update IF_WORK set batch = 1 where work_id = i.work_id" here. Exception handling also. 
    when not matched then  
     insert 
     (
     token, area, cust_id, status) 
     values 
     (i.token, i.area, i.cust_id, i.status) 
     -- I want to put "update IF_WORK set batch = 1 where work_id = i.work_id" here. Exception handling also. 
     ; 

    update IF_WORK set batch = 1;  
    commit; 

    exception 
    when others then rollback; 
end; 

,並遵循什麼我關心...

  1. 在當前的代碼,它運行for環比更新所有。需要個人控制。 (我必須更新IF_WORK表,只有成功數據)
  2. exception聲明的位置。我想回滾或提交每一行,而不是全部。但是,現在它將全部回滾。

所以我試圖將代碼更改爲一個merge程序和程序,它處理單行。但我知道不能使用when matched then的程序。

我該如何執行此操作?有沒有好的陳述/方法? 謝謝。

P.S因爲我已經和Java一起工作了很長時間,所以我提供的代碼看起來像Java中的後續代碼。

/* This is something I wanted 
    public static void main(String[] args) { 
     List<String> aList = new ArrayList<String>(); 
     for(String s : aList){ 
      try{ 
       * INSERT data !!! * 
      }catch(Exception e) { 
       * UPDATE data !!! * 
      } 
     } 
    } 
    */ 

    // Something I implemented for now 
    public static void main(String[] args) { 
     List<String> aList = new ArrayList<String>(); 
     try{ 
      for(String s : aList){ 
       * INSERT data !!! * 
      } 
     }catch(Exception e) { 
      * UPDATE all !!! * 
     } 
    } 

回答

0

因爲這還沒有得到回答,所以我想我會部分回答它。

要完全回答它並不容易,因爲我不知道數據庫設計的所有細節。

但是,通常情況下,您可以使用Oracle隱式遊標來開始循環訪問一組數據。

您仍然可以使用合併語句,現在插入或更新,只處理一行。

一些僞代碼如下:

create or replace procedure 
    mv_data 
is 
begin 

FOR ifwork IN (
    SELECT area, 
     cust_id, 
     status, 
     token, 
     work_id, 
     whatever_your_primary_key_column_is 
    FROM IF_WORK 
    WHERE batch=0 
) 
LOOP 
merge into WORK w 
    using (select ifwork.area, ifwork.cust_id, ifwork.status, ifwork.token, ifwork.work_id from dual) i 
    ...////rest of your MERGE statement here 

//update if_work set batch = 1 where whatever_your_primary_key_column_is=ifwork.whatever_your_primary_key_column_is 
    END LOOP; 



END; 
+0

感謝。這非常有幫助。我把過程放在'loop'裏面的'begin〜end;'塊中,並把異常聲明放到那裏。所以我可以通過行單元處理異常。再次感謝:D –

0

這是我如何解決這個與羅伯特的回答。

我做了2個程序(那些沒有exception聲明。處理那些在調用者過程)

  1. 插入原始表和其他
  2. 更新原始表和其他

比我把這稱爲loop聲明

create or replace procedure 
    mv_data 
is 
begin 
    for if_row in (
    select 
     * 
    from IF_WORK 
    where batch = 0 
) 
    loop 
    begin 
     procedureA(data ..., work_id); 
     exception 
     when dup_val_on_index then 
      update_both(data ..., work_id); 
     when others then rollback; 
    end; 
    end loop; 
end; 

我希望這將幫助其他人跟我一樣:d

  • 額外的建議總是歡迎