All*_*wis 2 oracle plsql exception
在PL/SQL过程中,我经常将语句包装在一个块中(即开始...结束),以便我可以从该语句中隔离异常.例如,如果我正在执行可能引发"no_data_found"的select,我可以在知道异常是由该语句引发的情况下处理它,但是让其他异常传播到该过程的主异常处理程序.
我想知道的是,这些额外的块是否会对性能产生任何影响.我知道引发异常会对性能产生影响,所以我从不依赖异常作为控制流机制.但块本身是否有任何影响?
例如,如果这个性能有任何差异:
procedure do_something
as
declare
some_var number;
begin
select some_value into some_var from some_table;
exception
when others then
raise_application_error(-20000, 'Exception: ' || sqlerrm, true);
end do_something;
Run Code Online (Sandbox Code Playgroud)
还有这个:
procedure do_something
as
declare
some_var number;
begin
begin
select some_value into some_var from some_table;
exception
when no_data_found then
some_var := -23; --some default value
end;
exception
when others then
raise_application_error(-20000, 'Exception: ' || sqlerrm, true);
end do_something;
Run Code Online (Sandbox Code Playgroud)
(我知道这段代码是荒谬的,但我希望它能说明我的意思!)
我真正关心的是没有引发异常时的性能 - 当出现异常时我可以接受性能下降.
它们似乎不是:
set timing on
set serveroutput on
declare
x number := 0;
begin
dbms_output.put_line('No inner blocks');
for i in 1..1000000 loop
x := x + 1;
end loop;
dbms_output.put_line(x);
end;
/
anonymous block completed
Elapsed: 00:00:00.095
No inner blocks
1000000
Run Code Online (Sandbox Code Playgroud)
在同一时间运行,每种方式都有一点变化,如:
declare
x number := 0;
begin
dbms_output.put_line('Nested inner blocks');
for i in 1..1000000 loop
begin
begin
begin
begin
x := x + 1;
exception
when others then
raise;
end;
exception
when others then
raise;
end;
exception
when others then
raise;
end;
exception
when others then
raise;
end;
end loop;
dbms_output.put_line(x);
end;
/
anonymous block completed
Elapsed: 00:00:00.090
Nested inner blocks
1000000
Run Code Online (Sandbox Code Playgroud)
当然,编译器可能正在删除冗余层,但我不确定它是否真的可以使用异常处理程序,因为它会影响结果.
我没有看到嵌套块有多深的限制 - 文档只是说'块可以嵌套'.您正在使用的模型,捕获特定错误并让其他人传播,这很好且非常标准 - 尽管显然在您的设计示例中没有必要,但您知道这一点.