请让我知道是否可以在oracle中同时捕获多个异常。不像 1 个用户定义,1 是预言机默认值。我需要同时捕获多个用户定义的异常。请让我知道该怎么做。
谢谢!
当然,有 - 如果我正确理解了这个问题。它被称为WHEN OTHERS
。虽然,人们通常会滥用它,尤其是当他们使用
exception
when others then
null;
end;
因为它成功地隐藏了可能出现的任何错误。WHEN OTHERS
在开发过程中是可以的,但在生产中可能真的很糟糕,特别是如果它不包含raise
。
是的,您可以从"当其他人"中执行所需的操作,如@Littlefoot或批量处理错误(此处未介绍(所示。但除此之外,您还可以在 WHEN 上有一个 OR 条件异常名称子句。它不是很有用,因为通常需要更多代码 2 个单独的 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。
我和小脚有一个非常小的分歧。我坚信,无论是否有意,在开发中编写的内容都将在生产中运行。很多时候,是无意的事情让你陷入麻烦。因此,即使在开发中,滥用WHEN OTHERS的例子也是无效的。