在PL / SQL过程中,我经常将语句包装在一个块中(即begin ... end),以便我可以从该语句中隔离异常。例如,如果我正在执行可能引发“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;
和此:
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;
(我知道这段代码是荒谬的,但我希望它能说明我的意思!)
我真正关心的是没有引发异常时的性能 - 当出现异常时我可以接受性能下降。
答案 0 :(得分:5)
他们似乎不会:
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
在同一时间运行,每次都有一点变化,如:
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
当然,编译器可能会删除冗余层,但我不确定它是否真的可以使用异常处理程序,因为它会影响结果。
我还没有看到嵌套块有多深的限制 - 文档只是说“块”可以嵌套'。您正在使用的模型,捕获特定错误并让其他人传播,这很好而且非常标准 - 尽管显然在您的人为例子中它是不必要的,但您知道这一点。