2017-05-09 41 views
-3
DECLARE 
    ERROR_COUNT NUMBER; 
    errno number; 
    e_msg varchar2(50); 
    e_idx varchar2(20); 

    TYPE emp_type IS TABLE OF emp_source%ROWTYPE; 
    EMP_VAR emp_type; 

    CURSOR c1 IS SELECT * FROM emp_source; 

BEGIN 
    OPEN c1; 

    loop 
     FETCH c1 BULK COLLECT INTO EMP_VAR; 

     BEGIN 
      FORALL i in 1 .. EMP_VAR.COUNT save exceptions  
      insert INTO emp_target (e_id,e_name,sal) values (EMP_VAR(i).E_ID,EMP_VAR(i).E_NAME,EMP_VAR(i).SAL); 

      FORALL i in 1 .. EMP_VAR.COUNT save exceptions  
      insert INTO department_target (dep_name) values (EMP_VAR(i).dep_name); 

     EXCEPTION 
      WHEN others THEN 
       ERROR_COUNT := sql%bulk_exceptions.count; 

       for i in 1 .. ERROR_COUNT 
       loop 
        errno := sql%bulk_exceptions(i).error_code; 
        e_msg := sqlerrm(-errno); 
        e_idx := sql%bulk_exceptions(i).error_index; 

        insert into emp_save_exc values(errno,e_msg,e_idx); 
       end loop; 
     END; 
     exit when c1%notfound; 
    end loop; 

    close c1; 
    commit; 
END; 
+2

请参阅http://stackoverflow.com/help/how-to-ask。我试着想象一下,如果一位同事来到我的办公桌上面打印出来并说出标题中的字眼,我会怎么做。我的回应可能会很短暂而且有点尖锐。 – BriteSponge

回答

2

你可以把周围的第一FORALL一个BEGIN/END块和处理这样的例外:

BEGIN 
    FORALL i in 1 .. EMP_VAR.COUNT save exceptions  
    insert INTO emp_target (e_id,e_name,sal) values (EMP_VAR(i).E_ID,EMP_VAR(i).E_NAME,EMP_VAR(i).SAL); 
EXCEPTION 
    WHEN ... 
END; 

你也可以把每个块成一个程序,让你的代码更有条理:

DECLARE 
    ... 
    PROCEDURE insert_emp_target (p_emp_var emp_type) IS 
    BEGIN 
     FORALL i in 1 .. EMP_VAR.COUNT save exceptions  
      insert INTO emp_target (e_id,e_name,sal) 
       values (EMP_VAR(i).E_ID,EMP_VAR(i).E_NAME,EMP_VAR(i).SAL); 
    EXCEPTION 
     WHEN ... 
    END; 

    PROCEDURE insert_dept_target (p_emp_var emp_type) IS 
    ... 
BEGIN 
    OPEN c1; 
    loop 
     FETCH c1 BULK COLLECT INTO EMP_VAR; 
     exit when c1%notfound; 
     insert_emp_target (emp_var); 
     insert_dept_target (emp_var); 
     ... 
    end loop; 
    close c1; 
    commit;  
END; 
+0

感谢您的回复,但我知道这个场景,这是简单的程序假设我已经在使用10插入内部,在这种情况下每个FORALL明智地使用BEGIN/END不是好主意。 – sygops

+0

为什么它不是一个好东西理念? –

+0

假设10次或更多,然后使用BEGIN/END,具体过程非常复杂。 – sygops