Да, вы можете делать то, что хотите, из «Когда другие», как указано @Littlefoot или ошибками массовой обработки (здесь не рассматривается). Но кроме того, в WHEN может быть предложение имени исключения условия OR. Это не очень полезно, так как обычно требует больше кода для двух отдельных условий WHEN, но это допустимый синтаксис. Далее демонстрируются различные методы определения ошибок и обработки исключений.
create table except_demo ( id integer, col1 varchar2(20));
insert into except_demo (id, col1)
select 5,'OK' from dual union all
select 6,'Too Many' from dual union all
select 6,'Still' from dual;
select id, count(*) from except_demo group by id;
create or replace procedure catcher(which_in integer, select_in boolean default False)
is
e_user_1 exception;
e_user_2 exception;
invalid_which_range exception;
appErr_inactive_acct exception;
sample_ora_error exception;
pragma exception_init (sample_ora_error, -00060);
rae exception;
rae_num constant integer := -20100;
pragma exception_init (rae, -20100);
col1_value except_demo.col1%type;
begin
dbms_output.put( 'Enter catcher(' || which_in || ') Result=>');
if which_in > 8
then raise invalid_which_range;
end if ;
if select_in
then
select col1
into col1_value
from except_demo
where id = which_in;
dbms_output.put_line('Select Successful 1 row selected.');
else
case which_in
when 1 then raise e_user_1;
when 2 then raise e_user_2;
when 3 then raise appErr_inactive_acct;
when 4 then raise sample_ora_error;
else raise_application_error(rae_num, 'Which_In=' || which_in || ' invalid. Please specify number 1-7 only');
end case;
end if;
exception
when e_user_1
then dbms_output.put_line('Error e_user_1'); -- user error
when e_user_2
then dbms_output.put_line('Error e_user_2');
when no_data_found or too_many_rows
then dbms_output.put_line('Select except_demo where id=' || which_in ||'; Returned 0 or more than 1 row. Must return exactly 1.' ); -- oracle predefined error
when sample_ora_error
then dbms_output.put_line('Ora Error:: ' || sqlerrm ); -- oracle error NOT predefined
when appErr_inactive_acct
then dbms_output.put_line('Error Account id ' || which_in || ' is inactive.'); -- user error
when rae
then dbms_output.put_line(sqlerrm);
end catcher;
declare
do_select boolean;
begin
for i in 1..9
loop
do_select := (i between 5 and 7);
catcher(i,do_select);
end loop;
exception
when others
then
dbms_output.put_line('Error returned from catcher=>' || sqlerrm);
raise;
end ;
drop procedure catcher;
drop table except_demo;
В реальной среде оператор dbms_output будет заменен записью сообщения и другой информации в таблицу журнала исключений, а НЕ в dbms_output.
У меня очень незначительные разногласия с Littlefoot. Я твердо верю, что то, что когда-либо написано в разработке, будь то предназначено или нет, будет запущено в производство. Слишком часто непреднамеренное приводит к неприятностям. Поэтому пример неправильного использования WHEN OTHERS недействителен даже в разработке .