2009-12-23 54 views
2

做下面的代码是不好的做法吗?写下它会不会发生在我身上?在PL/SQL中使用全局异常是不好的做法吗?

编辑:这只是一个例子。我不会使用dbms_output来进行任何实际的错误报告。

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; 
/

回答

8

与此相反,全局定义的用户例外是很好的做法。考虑一下包体的以下框架。

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过程中的异常处理更容易。

另外,请记住,有时候我们想要传播超出包的异常,说一个程序调用我们公开声明的过程。我们可以通过在包规范中定义我们的例外来做到这一点。这意味着其他proecdures可以引用他们...

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错误更有帮助。

+3

你需要小心RAISE my_x#。它会丢失发生原始错误的行号。这可能会使调试更加困难。你可以使用:DBMS_UTILITY.FORMAT_ERROR_BACKTRACE。 – David 2009-12-23 17:06:58

+1

公平点。像许多事情一样,总会有警告和扩展,在你知道它之前,你已经顺利地进入了OPP5 http://oreilly.com/catalog/9780596514464(1232pp)。但是显然日志和其他东西是错误处理的重要组成部分,应该在级联异常之前在错误点完成。 – APC 2009-12-23 17:24:20

2

看上去对我来说足够合理,只要你很高兴在中断条件之后恢复处理即可。如果要以某种方式记录中断,最好使用自治事务将一行插入日志表中。在完成整个过程之前,您不会看到DBMS_OUTPUT中的任何内容。然后你会立刻看到所有的DBMS_OUTPUT。

相关问题