【问题标题】:Catch PL/SQL error PLS-00306 iside PL/SQL methodCatch PL/SQL error PLS-00306 iside PL/SQL method
【发布时间】:2014-06-25 09:49:26
【问题描述】:

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

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

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

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

我的问题

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

【问题讨论】:

    标签: oracle dynamic plsql runtime-error


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

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

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

      如果编译错误是由dynamic PL/SQL 触发的,则编译中的单元将在没有错误的情况下创建,因为在编译期间不检查动态PL/SQL。而是在执行单元时在运行时引发错误并且可以捕获但只有ORA-code,而不是PLS-code。如果你有基于PLS-code 处理错误堆栈 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 错误代码。

      【讨论】:

        猜你喜欢
        • 2022-12-02
        • 2023-04-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多