在 oracle 中一次捕获多个异常
Posted
技术标签:
【中文标题】在 oracle 中一次捕获多个异常【英文标题】:Catching multiple exception at once in oracle 【发布时间】:2020-02-06 12:27:50 【问题描述】:请告诉我是否可以在 oracle 中同时捕获多个异常。不像 1 个用户定义和 1 个是 oracle 默认值。我需要同时捕获多个用户定义的异常。请告诉我该怎么做。
谢谢!
【问题讨论】:
能否提供您用于同时导致多个异常的代码? 我不明白这怎么可能。你执行一个操作。它会产生异常。你捕捉到了异常。唯一可能的额外异常将来自您在处理第一个异常时所做的事情。这并不是说您可以生成异常但忽略它们并继续处理,然后最后返回并收集您忽略的所有异常。 你的意思是bulk exception handling?还是DML Error Logging?如果这些都不能解决您的问题,您需要编辑您的问题,以提供有关您想要实现的目标的更多详细信息。 另一种选择,你的意思是单个代码单元可能会抛出几个异常中的一个,而你的异常块需要捕获并处理抛出的任何一个? 【参考方案1】:当然,如果我正确理解了这个问题的话。它被称为WHEN OTHERS
。不过,人们通常误用它,尤其是在使用时
exception
when others then
null;
end;
因为它成功隐藏了可能出现的任何错误。 WHEN OTHERS
在开发过程中是可以的,但在生产过程中可能真的很糟糕,特别是如果它不包含 raise
。
【讨论】:
【参考方案2】:是的,您可以按照@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。
我和 Littlefoot 有一点小分歧。我坚信在开发中编写的任何东西,无论是否有意,都会在生产中运行。很多时候,让你陷入困境的是意外。因此,误用 WHEN OTHERS 的示例即使在开发中也无效。
【讨论】:
以上是关于在 oracle 中一次捕获多个异常的主要内容,如果未能解决你的问题,请参考以下文章