tcbs_批量儲存過程_plsql事務_savepoint_異常

wisdomone1發表於2012-05-11
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/,如需轉載,請註明出處,否則將追究法律責任。

相關文章