代码之家  ›  专栏  ›  技术社区  ›  jva

在PL/SQL中使用全局异常是一种不好的做法吗?

  •  2
  • jva  · 技术社区  · 16 年前

    编辑:这只是一个例子。我不会将dbms_输出用于任何真正的错误报告。

    CREATE OR REPLACE PACKAGE my_package
    AS
    PROCEDURE master;
    END;
    /
    
    CREATE OR REPLACE PACKAGE BODY my_package
    AS
    
    my_global_interrupt EXCEPTION;
    
    
    PROCEDURE my_private_procedure
    IS
    BEGIN
      -- in case some flag is raised, raise exception to stop process and prepare for resume
      RAISE my_global_interrupt;
    END;
    
    PROCEDURE master
    IS
    BEGIN
      my_private_procedure;
    EXCEPTION
      WHEN my_global_interrupt THEN 
        dbms_output.put_line('global interrupt, ');
        -- prepare to resume
    END;
    
    END;
    /
    
    2 回复  |  直到 16 年前
        1
  •  8
  •   APC    14 年前

    相反,全局定义的用户异常是一种良好的做法。考虑下面的包体骨架。

    create or replace package body my_pkg 
    as
        my_x1 exception;
        my_x2 exception;
        my_x3 exception;
        PROCEDURE p1 is
        begin
            ...
        exception
            when no_data_found then raise my_x1;
        end p1;
        PROCEDURE p2 is
        begin
            ...
        exception
            when no_data_found then raise my_x2;
        end p2;
        PROCEDURE p3 is
        begin
            ...
        exception
            when no_data_found then raise my_x3;
        end p3;
        PROCEDURE master is
        begin
            p1;
            p2;
            p3;
        exception
            when my_x1 then do_this;
            when my_x2 then do_that;
            when my_x3 then do_the_other;
        end master;
    end my_pkg;
    /
    

    使用全局声明的异常会在 master 程序更简单。

    另外,请记住,有时我们希望将异常传播到包之外,比如说一个调用我们公开声明的过程的程序。我们可以通过在包规范中定义我们的异常来做到这一点。这意味着其他程序可以引用它们。。。

    SQL> begin
      2      my_pkg.master;
      3  exception
      4      when my_pkg.my_public_x1
      5          then dbms_output.put_line('oh no!');
      6  end;
      7  /
    oh no!
    
    PL/SQL procedure successfully completed.
    
    SQL>
    

    我们还可以将这些异常与特定的错误号关联起来,这样即使调用过程没有显式地处理它们,也可以识别它们。

    SQL> exec my_pkg.master
    BEGIN my_pkg.master; END;
    
    *
    ERROR at line 1:
    ORA-20999:
    ORA-06512: at "APC.MY_PKG", line 32
    ORA-06512: at line 1
    
    
    SQL>
    

    这(稍微)比一般的方法更有用 ORA-06510 错误。

        2
  •  2
  •   CMG    16 年前

    推荐文章