1. 程式人生 > 資料庫 >Oracle 錯誤日誌表及異常處理包詳解 附原始碼

Oracle 錯誤日誌表及異常處理包詳解 附原始碼

1 概述

1. 目的:'快速定位程式異常'

2. 包處理的核心思想:'自治事務' -- 自治事務的 "提交、回滾" 與 主事務 之間互不影響

3. 錯誤異常記錄邏輯大體一致,此處記錄,方便需要使用時複製、貼上

4. 驗證思路:通過執行報錯的過程,觀察 '程式執行結果' 和 '日誌表' 資料插入情況

2 效果演示

程式執行截圖:

在這裡插入圖片描述

日誌表查詢截圖:

在這裡插入圖片描述

3 原始碼

說明:
1. 測試中,共有 2 個使用者 -- 模擬實際開發場景
  (1) odsdata: 存放業務資料
  (2) odscde : 執行具體操作
  -- 為了方便測試,也可以去掉所有 '屬主 owner'

3.1 錯誤日誌表

CREATE TABLE odsdata.ods_program_error_log (
 error_log_id    VARCHAR2(10) NOT NULL,-- CONSTRAINT pk_opel_error_log_id PRIMARY KEY(error_log_id)
 owner        VARCHAR2(30),package_name    VARCHAR2(30),procedure_name   VARCHAR2(30),error_comment    VARCHAR2(1000),error_backtrace   VARCHAR2(400),error_stack     VARCHAR2(4000),call_stack     VARCHAR2(4000),error_date     DATE NOT NULL,oracle_execute_user VARCHAR2(50),um_id        VARCHAR2(50)
);

COMMENT ON TABLE odsdata.ods_program_error_log IS '程式錯誤日誌表';
COMMENT ON COLUMN odsdata.ods_program_error_log.error_log_id IS '錯誤日誌id';
COMMENT ON COLUMN odsdata.ods_program_error_log.owner IS '屬主';
COMMENT ON COLUMN odsdata.ods_program_error_log.package_name IS '包名';
COMMENT ON COLUMN odsdata.ods_program_error_log.procedure_name IS '過程名';
COMMENT ON COLUMN odsdata.ods_program_error_log.error_comment IS '錯誤備註';
COMMENT ON COLUMN odsdata.ods_program_error_log.error_backtrace IS '錯誤跟蹤';
COMMENT ON COLUMN odsdata.ods_program_error_log.error_stack IS '錯誤堆疊';
COMMENT ON COLUMN odsdata.ods_program_error_log.call_stack IS '呼叫堆疊';
COMMENT ON COLUMN odsdata.ods_program_error_log.error_date IS '錯誤時間';
COMMENT ON COLUMN odsdata.ods_program_error_log.oracle_execute_user IS 'oracle執行使用者';
COMMENT ON COLUMN odsdata.ods_program_error_log.um_id IS '操作人員um賬號';

GRANT SELECT,INSERT,UPDATE ON odsdata.ods_program_error_log TO odscde;

3.2 異常處理包

擴充套件:Oracle 序列詳解(sequence)

package:

CREATE OR REPLACE PACKAGE odscde.pkg_ods_error_handle IS
 --*************************************************
 --功能說明: 錯誤日誌
 --引數說明: i_procedure_name 程式名
 --     i_error_comment  錯誤備註(手工新增的)
 --呼叫函式:
 --修改記錄: create by YoYo 2020-12-17
 --*************************************************
 PROCEDURE exception_handle(i_procedure_name IN VARCHAR2,i_error_comment IN VARCHAR2);
END pkg_ods_error_handle;

package body:

CREATE OR REPLACE PACKAGE BODY odscde.pkg_ods_error_handle IS
 --*************************************************
 --功能說明: 錯誤日誌
 --引數說明: i_procedure_name 程式名
 --     i_error_comment  錯誤備註(手工新增的)
 --呼叫函式:
 --修改記錄: create by YoYo 2020-12-17
 --*************************************************
 PROCEDURE exception_handle(i_procedure_name IN VARCHAR2,i_error_comment IN VARCHAR2) IS
  PRAGMA AUTONOMOUS_TRANSACTION; -- !!! 自治事務
  v_log_info odsdata.ods_program_error_log%ROWTYPE;
 BEGIN
  v_log_info.error_log_id    := '1'; -- 異常錯誤id(一般是 "獲取序列號",此處僅演示)
  v_log_info.procedure_name   := i_procedure_name; -- 程式名
  v_log_info.error_comment    := i_error_comment;
  v_log_info.oracle_execute_user := sys_context('USERENV','SESSION_USER'); -- oracle執行使用者
  v_log_info.um_id        := nvl(sys_context('USERENV','OS_USER'),USER); -- 操作人員um賬號
  v_log_info.error_backtrace   := dbms_utility.format_error_backtrace; -- 錯誤跟蹤
  v_log_info.error_stack     := dbms_utility.format_error_stack; -- 錯誤堆疊
  v_log_info.call_stack     := dbms_utility.format_call_stack; -- 呼叫堆疊
  v_log_info.error_date     := SYSDATE;
 
  -- 可選列
  ---- 包屬主
  v_log_info.owner := substr(v_log_info.error_backtrace,instr(v_log_info.error_backtrace,'"',1) + 1,(instr(v_log_info.error_backtrace,'.',1) -
                instr(v_log_info.error_backtrace,1) - 1));
  ---- 包名
  v_log_info.package_name := substr(v_log_info.error_backtrace,1,2) - instr(v_log_info.error_backtrace,1) - 1));
 
  -- 插入資料
  INSERT INTO odsdata.ods_program_error_log
   (error_log_id,owner,package_name,procedure_name,error_comment,error_backtrace,error_stack,call_stack,error_date,oracle_execute_user,um_id)
  VALUES
   (v_log_info.error_log_id,v_log_info.owner,v_log_info.package_name,v_log_info.procedure_name,v_log_info.error_comment,v_log_info.error_backtrace,v_log_info.error_stack,v_log_info.call_stack,v_log_info.error_date,v_log_info.oracle_execute_user,v_log_info.um_id);
 
  COMMIT;
 END exception_handle;
END pkg_ods_error_handle;

3.3 測試程式

演示報錯:違反唯一性約束

stu_info:

CREATE TABLE odsdata.stu_info (
 sno  NUMBER(10) CONSTRAINT pk_si_sno PRIMARY KEY,sname VARCHAR2(50) NOT NULL
);

GRANT SELECT,UPDATE ON odsdata.stu_info TO odscde;

INSERT INTO odsdata.stu_info(sno,sname) VALUES(1,'瑤瑤');
COMMIT;

package:

CREATE OR REPLACE PACKAGE odscde.pkg_ods_error_test AS
 PROCEDURE ods_error_test(o_flag  OUT VARCHAR2,o_message OUT VARCHAR2);
END pkg_ods_error_test;

package body:

CREATE OR REPLACE PACKAGE BODY odscde.pkg_ods_error_test AS
 PROCEDURE ods_error_test(o_flag  OUT VARCHAR2,o_message OUT VARCHAR2) IS
  i_procedure_name VARCHAR2(30) := 'ods_error_test';
 BEGIN
  INSERT INTO odsdata.stu_info (sno,sname) VALUES (1,'瑤瑤');
  COMMIT;
 
  o_flag  := 'Y';
  o_message := '執行成功!';
 EXCEPTION
  WHEN OTHERS THEN
   o_flag  := 'N';
   o_message := '執行失敗!';
   pkg_ods_error_handle.exception_handle(i_procedure_name => i_procedure_name,i_error_comment => '' -- 關鍵入參、出參
                      );
 END ods_error_test;
END pkg_ods_error_test;

到此這篇關於Oracle 錯誤日誌表及異常處理包詳解 附原始碼的文章就介紹到這了,更多相關Oracle 錯誤日誌表內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!