嵌套块在PL/SQL过程中是否会对性能产生影响?

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)

(我知道这段代码是荒谬的,但我希望它能说明我的意思!)

我真正关心的是没有引发异常时的性能 - 当出现异常时我可以接受性能下降.

Ale*_*ole 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
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)

当然,编译器可能正在删除冗余层,但我不确定它是否真的可以使用异常处理程序,因为它会影响结果.

我没有看到嵌套块有多深的限制 - 文档只是说'块可以嵌套'.您正在使用的模型,捕获特定错误并让其他人传播,这很好且非常标准 - 尽管显然在您的设计示例中没有必要,但您知道这一点.