在异常内调用过程

时间:2018-10-18 19:28:34

标签: oracle stored-procedures plsql

我需要在其他过程中调用的异常内调用一个匿名过程。如下所示:

    procedure p1 is
    begin
      begin
        select 1 from dual;
      exception
        when no_data_found then
          p2;
      end;
    end;
    end p1;

    procedure p2 is
    [process..]
    end p2;
    begin
        p1;
    end;
    /

3 个答案:

答案 0 :(得分:0)

这样做没问题;但是,如果要运行匿名代码段,则它不是存储过程,因为它们是命名(即非匿名) )。

这是一个例子:

SQL> create or replace procedure p1 as
  2    l_dummy number(1);
  3  begin
  4    select 1 into l_dummy from dual where 1 = 2;
  5  exception
  6    when no_data_found then
  7      begin
  8        select 2 into l_dummy from dual;
  9        dbms_output.put_line('Exception, selected value = ' || l_dummy);
 10      end;
 11  end;
 12  /

Procedure created.

SQL> set serveroutput on
SQL> begin
  2    p1;
  3  end;
  4  /
Exception, selected value = 2

PL/SQL procedure successfully completed.

SQL>

如果要调用存储过程,也没有问题:

SQL> create or replace procedure p2 as
  2    l_dummy number(1);
  3  begin
  4    select 3 into l_dummy from dual;
  5    dbms_output.put_line('P2: selected value = ' || l_dummy);
  6  end;
  7  /

Procedure created.

SQL> create or replace procedure p1 as
  2    l_dummy number(1);
  3  begin
  4    select 1 into l_dummy from dual where 1 = 2;
  5  exception
  6    when no_data_found then
  7      p2;
  8  end;
  9  /

Procedure created.

SQL> begin
  2    p1;
  3  end;
  4  /
P2: selected value = 3

PL/SQL procedure successfully completed.

SQL>

如您所见,这两个选项均有效。

答案 1 :(得分:0)

您可以在p1内创建“匿名”(应该说嵌套)过程p2:

create or replace procedure p1 
is
    c INT;

    procedure p2 is
    begin
       DBMS_OUTPUT.put_line('Procedure p2');
    end p2;
begin
    select 1 INTO c from dual where 1=0;
    exception
    when no_data_found then
      p2;
end p1;
//

db<>fiddle demo

答案 2 :(得分:0)

您可以在匿名PL / SQL块中声明过程。您在匿名PL / SQL块中声明的任何过程将仅存在于该块中,并且仅在该块中可见。

例如,(从LittleFoot无耻地窃取p1p2的代码):

DECLARE
   -- Forward declaration for p2, so p1 can see it.  
   -- Alternatively, you could just put the whole definition of p2 here instead.
   procedure p2;

   procedure p1 as
      l_dummy number(1);
    begin
      select 1 into l_dummy from dual where 1 = 2;
    exception
      when no_data_found then
        p2;
    end p1;

    procedure p2 as
      l_dummy number(1);
    begin
      select 3 into l_dummy from dual;
      dbms_output.put_line('P2: selected value = ' || l_dummy);
    end p2;


BEGIN
      p1;
END;