oracle数据库中的过程/触发器错误日志

vom3gejh  于 2023-08-03  发布在  Oracle
关注(0)|答案(2)|浏览(312)

当我的过程/触发器或任何数据库对象发生错误时,数据库中是否有任何日志?
例如:当有人插入一个带有触发器的表,但触发器中发生了错误,我是否可以从数据库系统视图或数据库跟踪/警报日志中获得任何错误消息?
我在警报日志中发现了一些ora错误,但似乎只记录了数据库作业执行对象的错误。

yptwkmov

yptwkmov1#

由开发人员来编写如何处理异常的代码。如果没有异常处理,则异常将按照文档中的描述进行传播。如果你想捕获在pl/sql代码(包/函数/过程/触发器)中引发的异常,那么你可以实现一个像logger这样的开源工具。请注意,这需要对所有pl/sql代码进行代码更改。没有异常处理被许多人视为bug。

juzqafwq

juzqafwq2#

如果处理了异常(在PL/SQL中使用EXCEPTION处理),那么程序完全控制了对错误消息的处理,无论是记录它还是采取其他措施。客户可能永远看不到任何东西。开箱即用,Oracle不会记录错误(除非它们是核心错误-Oracle中的bug-如ORA-00600或ORA-07445,它们会立即终止您的流程;这些事件将在警报日志中,Oracle将创建特殊事件文件)。常规的编程异常不会出现在警报日志中。
然而,如果引发了一个异常,而这个异常一直到最外面的代码块都没有被处理,因此引发了一个异常到 * 客户端 *,那么是的,你可以在不修改代码的情况下记录这些异常,但是你必须在数据库/系统级别设置它。创建一个SERVERERROR ON DATABASE类型的系统触发器。以下是如何编写一个安全的日志,如果日志出现问题,它不会影响应用程序会话:

CREATE OR REPLACE TRIGGER SYSTEM.TR_SERVERERROR
AFTER SERVERERROR
ON DATABASE
DECLARE
  PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  IF ora_dict_obj_owner = SYS_CONTEXT('USERENV','CURRENT_SCHEMA') OR -- too dangerous, we could use components that are being modified and self-lock
     SYS_CONTEXT('USERENV','SESSIONID') = 0 OR -- background processes
     (SYS_CONTEXT('USERENV','SESSIONID') = 4294967295 AND (ora_dict_obj_owner = 'SYS' OR SYS_CONTEXT('USERENV','CLIENT_PROGRAM_NAME') NOT LIKE 'sqlplus%')) -- direct attached binaries, but allow sqlplus
  THEN
    NULL;
  ELSE
    EXECUTE IMMEDIATE 'BEGIN P_LOG_SERVER_ERROR; END;';
  END IF;
EXCEPTION 
  WHEN OTHERS THEN
    NULL;
END;
/

字符串
然后,您可以创建日志记录过程(这里是P_LOG_SERVER_ERROR),它使用各种变量和函数收集信息,其中一些变量和函数仅在系统触发器中可用:

server_error(1) -- error code, must reverse the sign
server_error_msg(1) -- error message
dbms_utility.format_error_stack -- full error stack
dbms_utility.format_error_backtrace -- backtrace
dbms_utility.format_call_stack -- call stack
utl_call_stack.concatenate_subprogram(utl_call_stack.subprogram(2)) -- erroring code unit
original_sql_txt(tab_sql) -- erroring SQL broken up into pieces, you have to reassemble


当然,可以从SYS_CONTEXT('USERENV',....)调用和查看v$sessionv$processv$session_connect_info等获取有关会话的大量信息。然后将所需的信息插入到一个特殊的表中。
然而,这种方法是为DBA准备的。为了创建这样的触发器,您需要ADMINISTER DATABASE TRIGGER权限,该权限太强大(而且很危险),不能给予非DBA。如果您不是DBA,但也不拥有要监视的代码,那么您可以与DBA讨论,让他们为您创建类似的东西。但是,如果您是有问题的代码的所有者,那么您应该在代码中编写适当的异常处理程序,并将触发器和数据库范围的日志记录留给DBA。

相关问题