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;
答案 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;