ITPub博客

首页 > Linux操作系统 > Linux操作系统 > tcbs_批量存储过程_plsql事务_savepoint_异常

tcbs_批量存储过程_plsql事务_savepoint_异常

原创 Linux操作系统 作者:wisdomone1 时间:2012-05-11 11:12:07 0 删除 编辑
TCBS后台的批量存储过程中,N次看到如下的代码处理逻辑,
lvsBatchActvMsg := 'Executing proc_SHADOWACCOUNTINGTXN';
      
        pack_SHADOWACCOUNTING.proc_SHADOWACCOUNTINGTXN(lvnFundTypArraySize,
                                                       lvasFundTypCd,
                                                       lvasFundTypDtlCd,
                                                       lvasClearCatCd,
                                                       lvanNbrOfItems,
                                                       lvanFundsAmt,
                                                       lvnBalCatArraySize,
                                                       lvasBalCatCd,
                                                       lvasBalTypCd,
                                                       lvanBalAmt,
                                                       lvnCurrAcctNbr,
                                                       lvnParentAcctNbr,
                                                       lvnParentRtxnNbr,
                                                       in_QUENBR,
                                                       in_APPLNBR,
                                                       in_QUESUBNBR,
                                                       NULL, --in_ALLOTSUBACCTNBR  IN  Rtxn.AllotSubAcctNbr%TYPE,
                                                       NULL, --in_ALLOTNBR     IN  Rtxn.AllotNbr%TYPE,
                                                       in_CASHBOXNBR,
                                                       lcsRtxnTypCd_SAOF,
                                                       NULL, --in_EXTRTXNDESCNBR IN  Rtxn.ExtRtxnDescNbr%TYPE,
                                                       NULL, --in_INTRRTXNDESCNBR  IN  Rtxn.IntrRtxnDescNbr%TYPE,
                                                       lvdEffDate,
                                                       lvdPostDate,
                                                       lcnOrigPersNbr_NULL,
                                                       lvnApprPersNbr,
                                                       lvnRunNtwkNodeNbr,
                                                       lcsRtxnStatCd_COMPLETE,
                                                       lvsRtxnSourceForBatch,
                                                       NULL,
                                                       'Y', --in_RTXNREASONCD, in_POSTYN 
                                                       lcsCommit_NO,
                                                       in_DEBUGYN,
                                                       in_TXNSEQNBR,--20120428 翟勋杨 特殊交易流水
                                                       lvnRtxnNbr,
                                                       lvnErrorNbr,
                                                       lvsSubProcErrorMsg,
                                                       lvsBatchOracleMsg);
      
        IF (lvnErrorNbr > 0) THEN
          lvbErrorExists := TRUE;
          ROLLBACK TO SAVEPOINT sav_CURRTRAN;
          proc_BATCHERROR(in_QUENBR,
                          in_APPLNBR,
                          in_QUESUBNBR,
                          lvsBatchActvMsg,
                          lvsBatchOracleMsg,
                          lvnCurrAcctNbr,
                          lvnErrorNbr);
        
          IF (lvnErrorNbr > 0) THEN
            lvsBatchOracleMsg := SUBSTR(SQLERRM(-lvnErrorNbr), 1, 100);
            lvsBatchActvMsg   := 'Executing: proc_BATCHERROR for ' ||
                                 lvnCurrAcctNbr;
            RAISE OSI_GENERAL_ERROR;
          END IF;
        END IF;
      END IF; -- ( NOT lvbErrorExists ) AND ( lvsShadowAcctgYN = 'Y' )

  上述代码包含了保存点.if代码块,异常,异常后的处理代码
那么我的测试要点:
                   
1,发生异常时,会执行到保存点吗
2,保存点执行后(即:rollback to 执行后),还会继续执行后续的代码,还是直接退出存储过程
3,exception异常代码块,一直对于when others then的理解,
 others是可以捕获所有的oracle异常吗,这样我就可以编写相关的处理代码,不至于让代码中断了.代码的健壮性就增强了
SQL> declare
  2  v_a varchar2(10);
  3  begin
  4  insert into log_test values(1,'zxy');
  5  savepoint sp1;
  6  v_a:='mv';
  7  insert into other_log values(2,'zxz');
  8  if v_a='mv' then

 //保存点sp1的作用,在后面执行rollback to sp1,就会保存sp1之前代码所作的工作,而不会完全rollback,尤其对于金融系统,利用游标处理若干账号的业务情形
  9  rollback to  sp1;
   //dbms_output仅用于调试显示用
 10  dbms_output.put_line('开始执行rollback to之后的代码');
 11  
     //在TCBS后台的大量存储过程中采用了多个begin exception end的代码块
 //以前不太懂,这样就会增强模块化,每块代码具有独立的处理能力,再者
 //处理逻辑显得清晰
    //从业务流程上看也很清楚,一环扣一环,直至流程结束
 12  begin

    //注:log_test表的第二列是varchar2(10)的大小,故意insert超过列大小的数据
   //以测试when others then是否可以捕获到此异常
 13  insert into log_test values(88,'after rollback to');
 14  exception //异常块关键字 exception,而非exceptions
  //采取when others then的作用就是在上述insert子句出错,整个plsql或者
  存储过程可以继续执行,不会导致中断
 15  when others then //在此我们只写一种异常处理分支,当然实际情况可以有多个类似的分支

   //在此我只是用关键字sqlerrm及sqlcode显示insert语句具体异常的相关信息
  //sqslerrm表示oracle出错的原因(含:文字及错误号),sqlcode仅是oracle错误号
 16  dbms_output.put_line(sqlerrm||sqlcode);

    //编写如下insert into 语句,为了测试在捕获后insert into之类的dml语句可以继续
 //执行吗,答案是可以执行
 17  --捕获错误的insert语句后,修正错误insert语句后再次执行它
 18  insert into log_test values(88,'re_after');
 19  end;
 20  --commit;
 21  end if;
 22  end;
 23  /

开始执行rollback to之后的代码
ORA-12899: 列 "SCOTT"."LOG_TEST"."LOGMAN" 的值太大 (实际值: 17, 最大值: 10)-12899

//直接在本会话查询log_test的记录,发现没有两个记录,就是没有了
//insert into other_log values(2,'zxz')的相关记录,因为代码块有rollback to,这就是//它的作用
PL/SQL procedure successfully completed

SQL> select * from log_test;

                                    SEQ LOGMAN
--------------------------------------- ----------
                                     88 re_after
                                      1 zxy

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9240380/viewspace-723330/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
提供针对oracle初学者及进阶的数据库培训,欢迎大家咨询: 微信: wisdomone 微信公众号: lovedb qq: 305076427 微博: wisdomone9

注册时间:2008-04-04

  • 博文量
    2149
  • 访问量
    11890835