Oracle 11g - 如何在合并语句中执行多行?

Oracle 11g - How to execute multiple line in merge statement?

我现在正在使用 merge into 语句,但它不符合要求。当前代码如 ...

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 table 只有成功数据)
  2. exception 语句的位置。我想为每一行而不是所有行回滚或提交。但是,目前它将全部回滚。

所以我尝试将代码更改为一个 merge 过程和处理单行的过程。但是我知道不能在when matched then.

处使用程序

我该如何实施?有什么好的 statement/method 吗? 谢谢。

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 !!! *
        }
    }

由于还没有人回答,我想我会部分回答。

很难完整回答,因为我不知道你的数据库设计的所有细节。

但是,一般来说,您可以使用 Oracle 隐式游标开始循环访问一组数据。

您仍然可以使用 Merge 语句,现在插入或更新,只处理一行。

部分伪代码如下:

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;

这就是我用罗伯特的回答解决这个问题的方法。

我制作了 2 个程序(那些没有 exception 语句。在调用程序中处理它们)

  1. 插入原件table和另一个
  2. 更新原来的table和另一个

比我在 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

  • 随时欢迎补充建议