調試存儲過程與declare語句差別

 當應用有調用存儲過程,而節點有幾十個或者上百個,找錯是否是一個很麻煩的事情,這個時候,我建議寫到數據庫中,下面是我作的一個demo.

 一、 創建錯誤日誌記錄表html

drop table PUB_PROC_ERR_LOG purge;
create table PUB_PROC_ERR_LOG
 (
   LOG_ID      NUMBER,
   MODULE_NAME VARCHAR2(100),
   PROC_NAME   VARCHAR2(100),
  ERR_TIME    DATE,
   SQL_CODE    VARCHAR2(50),
   SQL_ERRM    VARCHAR2(100),
   ERR_CONTENT VARCHAR2(500)
 );
comment on column PUB_PROC_ERR_LOG.LOG_ID is '主鍵';
comment on column PUB_PROC_ERR_LOG.MODULE_NAME  is '模塊名稱';
comment on column PUB_PROC_ERR_LOG.PROC_NAME  is '存儲過程名稱';
comment on column PUB_PROC_ERR_LOG.ERR_TIME  is '報錯時間';
comment on column PUB_PROC_ERR_LOG.SQL_CODE  is 'SQLCODE';
comment on column PUB_PROC_ERR_LOG.SQL_ERRM  is 'SQLERRM'; 
comment on column PUB_PROC_ERR_LOG.ERR_CONTENT  is '報錯的具體行';

 二、表主鍵的序列sql

create sequence SEQ_RECORD_PROC_ERR
 minvalue 1
 maxvalue 9999999999999999999999999999
 start with 21
 increment by 1
 
cache 20;

 三、通用記錄錯誤存儲過程,用自治事務數據庫

CREATE OR REPLACE PROCEDURE 
 record_proc_err_log(module_name varchar2,
                 proc_name   varchar2,
                 v_SQLCODE   varchar2,
                 v_SQLERRM   varchar2,
                 v_err_line  varchar2) is
   PRAGMA AUTONOMOUS_TRANSACTION;
 BEGIN
   insert into pub_proc_err_log
     (log_id,
      module_name,
      proc_name,
      err_time,
      sql_code,
      sql_errm,
      err_content)
   values
     (seq_record_proc_err.nextval,
      module_name,
      proc_name,
      sysdate,
      v_SQLCODE,
      v_SQLERRM,
      v_err_line);
   commit;
 END record_proc_err_log;

 四、測試oop

create or replace procedure proce_test is
begin
  for rec in (SELECT T1.*
                FROM XX.V_PROD_INST_INFO T1, AUDI_SAMPLE_NM T2
               where t1.PROD_INST_ID = t2.prod_inst_id) loop
    begin
      INSERT INTO ASA_PROD_INFO_PROV_NM_BK
        (PROV_CODE,
         PROD_INST_ID,
         PROD_ID,
         EXT_PROD_ID,
         ACC_NUM,
         ACCOUNT,
         PAYMENT_MODE_CD,
         OWNER_CUST_ID,
         STATUS_CD,
         AUDI_DATE,
         AUDI_BATCH)
      values
        ('NM',
         rec.PROD_INST_ID,
         rec.PROD_ID,
         rec.EXT_PROD_ID,
         rec.ACC_NUM,
         rec.ACCOUNT,
         rec.PAYMENT_MODE_CD,
         rec.OWNER_CUST_ID,
         rec.STATUS_CD,
         sysdate,
         '2017-12');
      commit;
      Exception
        WHEN OTHERS 
      Then
        record_proc_err_log('moduleName',
                            'proce_test()',
                            SQLCODE,
                            SQLERRM,
                            substr(dbms_utility.format_error_backtrace,1,400));
    end;
 end loop;
end proce_test;

 五、編譯存過 調試存過,輸入參數,點擊放大鏡(開始調試器)開始debug存過測試

六、執行存過(以下兩種方式):debug

 

等價於以下存過/語句塊,給表裏面插入數據,並顯示錯誤信息。此種方式記錄的錯誤信息在語句執行結束後在輸出窗口顯示3d

create or replace procedure proce_test is
  --is下面爲變量聲明區域
  iStep   number;
  iCount  number;
begin
  --變量初始化區域
  iStep  := 0;
  iCount := 0;
   <<outer_loop>>

  for rec in (SELECT T1.*
                FROM XX.V_PROD_INST_INFO T1, AUDI_SAMPLE_NM T2
               where t1.PROD_INST_ID = t2.prod_inst_id) loop
    begin
      INSERT INTO ASA_PROD_INFO_PROV_NM_BK
        (PROV_CODE,
         PROD_INST_ID,
         PROD_ID,
         EXT_PROD_ID,
         ACC_NUM,
         ACCOUNT,
         PAYMENT_MODE_CD,
         OWNER_CUST_ID,
         STATUS_CD,
         AUDI_DATE,
         AUDI_BATCH)
      values
        ('NM',
         rec.PROD_INST_ID,
         rec.PROD_ID,
         rec.EXT_PROD_ID,
         rec.ACC_NUM,
         rec.ACCOUNT,
         rec.PAYMENT_MODE_CD,
         rec.OWNER_CUST_ID,
         rec.STATUS_CD,
         sysdate,
         '2017-12');
      commit;
      Exception
        WHEN OTHERS 
      Then
        record_proc_err_log('moduleName',
                            'proce_test()',
                            SQLCODE,
                            SQLERRM,
                            substr(dbms_utility.format_error_backtrace,1,400));
		end;
		exit outer_loop; 
    iStep  := iStep + 1;
    iCount := iCount + 1;
    if iStep = 2000 then
      iStep := 0;
      insert into CS_COUNT_LOG values ('CP', sysdate, iCount);
      commit;
    end if;
  end loop;
  insert into CS_COUNT_LOG values ('CP', sysdate, iCount);
  commit;
end;
end proce_test;

 

declare

  iStep   number;

  iCount  number;

  sErrstr varchar2(1024);

begin

  iStep  := 0;

  iCount := 0; 

  <<outer_loop>>

  for rec in (SELECT T1.*

                FROM DC_ALL_NM.V_PROD_INST_INFO T1, AUDI_SAMPLE_NM T2

               where t1.PROD_INST_ID = t2.prod_inst_id) loop 

    begin   

      INSERT INTO ASA_PROD_INFO_PROV_NM_BK

        (PROV_CODE,

         PROD_INST_ID,

         PROD_ID,

         EXT_PROD_ID,

         ACC_NUM,

         ACCOUNT,

         PAYMENT_MODE_CD,

         OWNER_CUST_ID,

         STATUS_CD,

         AUDI_DATE,

         AUDI_BATCH)

      values

        ('NM',

         rec.PROD_INST_ID,

         rec.PROD_ID,

         rec.EXT_PROD_ID,

         rec.ACC_NUM,

         rec.ACCOUNT,

         rec.PAYMENT_MODE_CD,

         rec.OWNER_CUST_ID,

         rec.STATUS_CD,

         sysdate,

         '2017-12');

    exception

      when others then

        sErrstr := '寫表 xxxxxx 出錯SQL:' || rec.PROD_INST_ID ||

                   rec.PAYMENT_MODE_CD || rec.PROD_ID || rec.EXT_PROD_ID ||

                   rec.OWNER_CUST_ID || ',SQL??:' || SQLCODE || ',' ||

                   Sqlerrm || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE;       

        exit outer_loop;

        return;

    end; 

    iStep  := iStep + 1;

    iCount := iCount + 1;

    if iStep = 2000 then

      iStep := 0;

      insert into CS_COUNT_LOG values ('CP', sysdate, iCount);

      commit;

    end if;

  end loop; 

  dbms_output.put_line(sErrstr); 

  insert into CS_COUNT_LOG values ('CP', sysdate, iCount);

  commit;

end;

/
 

 

相關文章
相關標籤/搜索