2015-09-21 32 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

  • 额外的建议总是欢迎