如果第一个forall记录异常发生,第二个forall不执行该怎么办?

时间:2017-05-09 10:53:55

标签: oracle plsql

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;

1 个答案:

答案 0 :(得分: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;