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

问题描述 投票:0回答:2

当我的过程/触发器或任何数据库对象发生错误时,数据库中是否有任何日志?

例如:当有人使用触发器插入表但触发器中发生错误时,我可以从数据库系统视图或数据库跟踪/警报日志中获取任何错误消息吗?

我在警报日志中发现了一些ora错误,但似乎只记录了数据库作业执行的对象的错误。

oracle exception plsql rdbms
2个回答
0
投票

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


0
投票

如果处理了异常(在 PL/SQL 中使用

EXCEPTION
处理),则程序可以完全控制如何处理错误消息,无论是记录它还是采取其他操作。客户可能永远看不到任何东西。开箱即用,Oracle 不会记录错误(除非它们是核心错误 - Oracle 中的错误 - 例如 ORA-00600 或 ORA-07445,它们会立即终止您的进程;这些错误将出现在警报日志中,并且 Oracle 将创建特殊事件文件) 。常规编程异常不会进入警报日志。

但是,如果引发异常,且not一直处理到最外层代码块,从而向client引发异常,那么是的,您可以在不修改代码的情况下一般记录这些异常,但您必须对其进行设置在数据库/系统级别。考虑创建一个类型为

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$session
v$process
v$session_connect_info
等获得有关会话的大量信息。然后将所需的信息插入到用于此目的的特殊表中。

但是,此方法是供 DBA 使用的。为了创建这样的触发器,您需要

ADMINISTER DATABASE TRIGGER
权限,该权限过于强大(且危险),无法授予非 DBA。如果您不是 DBA,但也不拥有您想要监控的代码,您可以与您的 DBA 讨论,让他们为您创建类似的内容。但是,如果您是相关代码的所有者,那么您应该在代码中编写自己的正确异常处理程序,并将触发器和数据库范围的日志记录留给 DBA。

© www.soinside.com 2019 - 2024. All rights reserved.