将记录日志单独存放成一个普通的存储过程
CREATE OR REPLACE PROCEDURE record_error
IS
l_code PLS_INTEGER := SQLCODE;
l_mesg VARCHAR2(32767) := SQLERRM;
BEGIN
INSERT INTO error_log (error_code
, error_message
, backtrace
, callstack
, created_on
, created_by)
VALUES (l_code
, l_mesg
, sys.DBMS_UTILITY.format_error_backtrace
, sys.DBMS_UTILITY.format_call_stack
, SYSDATE
, USER);
end;
在别的存储过程的异常处理中使用
DECLARE
i_number NUMBER (1);
BEGIN
i_number:=100;
insert into student values(4,'d',99);
insert into student values(5,'e',100);
EXCEPTION
WHEN OTHERS
THEN
record_error();
raise;
END;
i_number:=100这个会跑错误出来,但是在执行后,error_log中没有记录,异常回滚掉了,需要将这个存储过程标记成自制事务,
CREATE OR REPLACE PROCEDURE record_error
IS
PRAGMA AUTONOMOUS_TRANSACTION;
l_code PLS_INTEGER := SQLCODE;
l_mesg VARCHAR2(32767) := SQLERRM;
BEGIN
INSERT INTO error_log (error_code
, error_message
, backtrace
, callstack
, created_on
, created_by)
VALUES (l_code
, l_mesg
, sys.DBMS_UTILITY.format_error_backtrace
, sys.DBMS_UTILITY.format_call_stack
, SYSDATE
, USER);
commit;
end;
这样在抛出异常的时候就能捕获异常了,下面的解释来自:http://blog.sina.com.cn/s/blog_66cd71d90100shw7.html
ORACLE8i的AUTONOMOUS TRANSACTION(自治事务,以下AT)是一个很好的回答。
AT 是由主事务(以下MT)调用但是独立于它的事务。在AT被调用执行时,MT被挂起,在AT内部,一系列的DML可以被执行并且commit或rollback.
注意由于AT的独立性,它的commit和rollback并不影响MT的执行效果。在AT执行结束后,主事务获得控制权,又可以继续执行了。