捕获PL / SQL错误PLS-00306 iside PL / SQL方法

时间:2014-05-08 06:32:08

标签: oracle dynamic plsql runtime-error

我正在使用动态PL / SQL运行方法(方法名称由最终用户发送)(例如:EXECUTE IMMEDIATE)。

当方法签名不匹配时,引发错误ORA-06550(堆栈中也提到了PLS-00306)。

当方法签名与所需签名不匹配时,我需要引发自定义消息。

所以我在PL / SQL异常块中捕获ORA-06550并引发错误。只注意到ORA-06550引发了任何无效的PL / SQL代码(包括方法签名不匹配)

我的问题

  1. ORA类型消息和PLS类型消息之间有什么区别。不能捕获PLS类型的消息(例如:PLS-00306),就像捕获ORA类型消息一样(例如:ORA-06550)。如果可能的话怎么样?
  2. 如果不可能如何捕获签名不匹配? (除了针对USER_ARGUMENTS
  3. 运行查询

2 个答案:

答案 0 :(得分:1)

PLS - 错误是PL / SQL编译器的编译错误,无法直接捕获运行时,因为它们包含ORA - 错误。

如果编译错误由 static PL / SQL触发,则编译中的单元将被创建为无效,并且单元的执行会触发PLS-00905(包含ORA-06550)。

如果编译错误由 dynamic PL / SQL触发,则编译中的单元创建没有错误,因为在编译期间未检查动态PL / SQL。相反,错误是在执行单元时提高运行时间并且可以被捕获但只有ORA - 代码,而不是PLS - 代码。如果您基于PLS做了某些事情 - 代码处理错误堆栈 string

create or replace function get_custom_error(p_pls_code in varchar2) return varchar2 is
begin
  return
    case p_pls_code
      when 'PLS-00201' then 'this is my custom error code'
      else 'unknown PLS error code'
    end;
end;
/
show errors

create or replace procedure foo is
  plsql_compilation_error exception;
  pragma exception_init(plsql_compilation_error, -6550);
  v_a number;
begin
  dbms_output.put_line('foo started');
  execute immediate 'begin bar; end;';
  dbms_output.put_line('foo ended normally');
exception
  when plsql_compilation_error then
    declare
      v_pls_error_code constant varchar2(20) := 
        regexp_substr(dbms_utility.format_error_stack,
                      '(PLS-[[:digit:]]+):', 1, 1, '', 1);
    begin
      dbms_output.put_line(get_custom_error(v_pls_error_code));
    end;
end;
/
show errors

执行示例:

SQL> exec foo
foo started
this is my custom error code

PL/SQL procedure successfully completed.

SQL> 

Oracle Database Error Messages中列出并解释了所有Oracle错误代码。

答案 1 :(得分:0)

1)ORA和PLS之间的区别在于哪个引擎引发了异常。错误堆栈顶部的错误显示一般错误。更深层次的错误提供了越来越多的细节。像ORA-06550一样,因为PLS-00306发生了

2)在任何有潜在危险的地方,你应该添加BEGIN ... EXCEPTION ... END。要区分任何ORA错误,您可以在父块中声明异常,并使用PRAGMA指令将其与错误代码链接。

begin
  …
  begin
    …
    execute immediate …
  exception
    when …
  end;
  …
end;