使用 pl/sql 过程记录错误和处理异常

Posted

技术标签:

【中文标题】使用 pl/sql 过程记录错误和处理异常【英文标题】:Using a pl/sql procedure to log errors and handle exceptions 【发布时间】:2015-09-14 15:53:42 【问题描述】:

到目前为止,堆栈溢出,oracle 论坛和文档一直是我学习 PLSQL 的最佳朋友。我在这里遇到了一个问题。任何建议表示赞赏。我正在编写一个程序,用于记录程序包可能遇到的任何错误并将它们记录到我创建的错误日志表中。到目前为止,这是我的代码。

CREATE OR REPLACE PROCEDURE APMS.test_procedure AS

    procedure write_error_log (errcode number, errstr varchar2, errline varchar2) is
    pragma autonomous_transaction; 
    -- this procedure stays in its own new private transaction
    begin                         
          INSERT INTO error_log
               (ora_err_tmsp,
                      ora_err_number,
                      ora_err_msg,
                      ora_err_line_no)
          values (CURRENT_TIMESTAMP,
                  errcode,
                  errstr,
                  errline);
          COMMIT;  -- this commit does not interfere with the caller's transaction.
    end write_error_log;

 BEGIN
    INSERT INTO mockdata
        VALUES ('data1', 'mockname', 'mockcity'); 

  exception when others then             
    write_error_log(sqlcode,sqlerrm,dbms_utility.format_error_backtrace);
    raise; 
 END test_procedure;
/

在程序中,我目前使用模拟数据表来引发无效数字错误并将其记录到 error_log 表中。在这一点上,错误日志表被证明是正常的,并插入了所需的数据。对我来说,下一步是使用此过程在其他程序的异常处理程序中使用,以便捕获错误并将其记录到表中。目前,我的程序仅对 mock_data 表是唯一的。我的导师/上级告诉我,我需要向这个程序传递一些参数才能在其他包和异常处理程序中使用它。我只是有点麻烦。任何帮助将不胜感激!

【问题讨论】:

我认为您的过程可用于在任何存在 mock_data 表的情况下记录错误。您可以从任何包或异常处理程序中调用它来记录错误。抱歉,我可能不太明白你的问题。 对不起,我正在尝试删除 mock_data 表并将此过程用于架构中的其他包和过程来记录这些错误。 mock_data 表纯粹用于测试目的。另外,我很确定你在我的最后一个问题上帮助了我哈哈,所以谢谢你的帮助 write_error_log 应该定义为一个单独的过程,而不是定义为test_procedure 中的嵌套过程。我将创建一个包,其中包含 write_error_log 过程以及您需要的任何其他与日志记录相关的过程。然后,您可以在整个代码中调用 error_log.write_error_log 过程。 是的,但是您应该有一个将存储所有这些错误的表,或者您希望将表名作为过程参数传递? 我有一个 error_log 表,其中将存储错误。该表在其称为 error_log 的代码中显示。 【参考方案1】:

Steven Feuerstein 在 Oracle Magazine 上写了几篇关于如何处理 PLSQL 中的错误的文章。他为此提供了一个小框架(errpkg)。 DRY 原则(不要重复自己)是他的口头禅!

https://resources.oreilly.com/examples/0636920024859/blob/master/errpkg.pkg

【讨论】:

链接失效 @Toolkit 我在 Stevens Book "Oracle PLSQL Programming 6th Edition" 中找到了对 errpkg 的引用【参考方案2】:

首先,你应该让你的调用者传入errline。这是非常乏味的!当开发人员需要插入一两行代码时会发生什么?在那之后,他们是否需要更新对write_error_log 的每次调用以更新行号?您的write_error_log 应该使用dbms_utility.format_call_stack(或者更方便的12c 变体......没有它的名字方便)来确定哪一行代码发出了对write_error_log 的调用。

然后,您应该有一个称为write_exception 的第二个过程。所有需要做的就是这样的:

write_error_log (SQLCODE, SUBSTR (DBMS_UTILITY.format_error_stack || DBMS_UTILITY.format_error_backtrace, 1, 4000));

【讨论】:

我对@9​​87654328@部分不太理解,开发者只需要通过DBMS_UTILITY.format_error_backtrace就可以得到行错误(write_error_log(sqlcode,sqlerrm,dbms_utility.format_error_backtrace)),如果添加就不需要更新一两行。我认为使用 DBMS_UTILITY.format_error_stack 获取完整的错误消息可能是个好主意 如果所有你希望能够记录的是SQL异常,那么你根本不需要接受任何参数。您的日志记录过程可以调用 DBMS_UTILITY.FORMAT_ERROR_STACK / BACKTRACE 并完成。 是的,你是对的,你不需要把它设置为参数,你可以直接从过程中调用。

以上是关于使用 pl/sql 过程记录错误和处理异常的主要内容,如果未能解决你的问题,请参考以下文章

Oracle的PL_SQL的异常处理

Oracle-4 - :超级适合初学者的入门级笔记:plsql,基本语法,记录类型,循环,游标,异常处理,存储过程,存储函数,触发器

PL/SQL数据开发那点事

如何修改我的 PL/SQL 过程以进行异常处理?

PL/SQL 异常和错误处理

Oracle存储过程的异常处理