plsql自治事务在异常中的使用

将记录日志单独存放成一个普通的存储过程

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执行结束后,主事务获得控制权,又可以继续执行了。


你可能感兴趣的:(plsql自治事务在异常中的使用)