當應用有調用存儲過程,而節點有幾十個或者上百個,找錯是否是一個很麻煩的事情,這個時候,我建議寫到數據庫中,下面是我作的一個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; /