本文主要介绍如何记录存储过程执行详细日志,统计存储过程执行时间,实现逻辑如下:
-
创建一个序列,用于标识[存储过程,函数,触发器]执行先后顺序
create sequence SEQ_PROGRAM_EXECUTE_LOG
minvalue 1
maxvalue 1000000000000
start with 1
increment by 1
cache 100
cycle
order;
- 创建日志表,用于存储[存储过程,函数,触发器]执行日志
CREATE TABLE PROGRAM_EXECUTE_LOG
PROGRAM_NAME VARCHAR2(1000),
IS_SUCCEED CHAR(1),
LOG_DATE DATE,
EXECUTE_MSG CLOB,
TIME_CONSUMING NUMBER,
EXECUTE_ORDER NUMBER,
EXECUTE_BEGINTIME TIMESTAMP(6),
EXECUTE_ENDTIME TIMESTAMP(6),
PROCESS_FLAG VARCHAR2(10) DEFAULT 'N'
comment on table PROGRAM_EXECUTE_LOG
is '过程、函数、触发器执行性能日志';
comment on column PROGRAM_EXECUTE_LOG.program_name
is '程序名称';
comment on column PROGRAM_EXECUTE_LOG.is_succeed
is '执行结果(成功Y,失败N)';
comment on column PROGRAM_EXECUTE_LOG.log_date
is '日志时间';
comment on column PROGRAM_EXECUTE_LOG.execute_msg
is '执行详细信息';
comment on column PROGRAM_EXECUTE_LOG.time_consuming
is '耗时';
comment on column PROGRAM_EXECUTE_LOG.execute_order
is '流水号-SEQ_PROGRAM_EXECUTE_LOG';
comment on column PROGRAM_EXECUTE_LOG.execute_begintime
is '执行开始时间';
comment on column PROGRAM_EXECUTE_LOG.execute_endtime
is '执行结束时间';
comment on column PROGRAM_EXECUTE_LOG.process_flag
is '处理标识(已处理Y,未处理N)';
CREATE INDEX PROGRAM_EXECUTE_LOG_IDX1 ON PROGRAM_EXECUTE_LOG (EXECUTE_ORDER);
CREATE INDEX PROGRAM_EXECUTE_LOG_IDX2 ON PROGRAM_EXECUTE_LOG (TIME_CONSUMING);
CREATE OR REPLACE FUNCTION F_TIMESTAMP_DIFF(ENDTIME IN TIMESTAMP,
STARTTIME IN TIMESTAMP)
RETURN INTEGER AS
STR VARCHAR2(50);
MISECOND INTEGER;
SECONDS INTEGER;
MINUTES INTEGER;
HOURS INTEGER;
DAYS INTEGER;
BEGIN
STR := TO_CHAR(ENDTIME - STARTTIME);
MISECOND := TO_NUMBER(SUBSTR(STR, INSTR(STR, ' ') + 10, 3));
SECONDS := TO_NUMBER(SUBSTR(STR, INSTR(STR, ' ') + 7, 2));
MINUTES := TO_NUMBER(SUBSTR(STR, INSTR(STR, ' ') + 4, 2));
HOURS := TO_NUMBER(SUBSTR(STR, INSTR(STR, ' ') + 1, 2));
DAYS := TO_NUMBER(SUBSTR(STR, 1, INSTR(STR, ' ')));
RETURN DAYS * 24 * 60 * 60 * 1000 + HOURS * 60 * 60 * 1000 + MINUTES * 60 * 1000 + SECONDS * 1000 + MISECOND;
END;
CREATE OR REPLACE PROCEDURE SYS_SAVELOG(PROGRAM_NAME VARCHAR2,
IS_SUCCEED VARCHAR2,
EXECUTE_MSG CLOB,
BEGIN_TIME TIMESTAMP
) AS
V_PROGRAM_NAME VARCHAR2(1000) := SUBSTRB(PROGRAM_NAME, 1, 1000);
V_IS_SUCCEED CHAR(1) := SUBSTR(IS_SUCCEED, 1, 1);
V_BEGIN_TIME TIMESTAMP := BEGIN_TIME;
PRAGMA AUTONOMOUS_TRANSACTION;
调用方式:
1.正常日志:PROC_SAVELOG(V_PROC_NAME, 'Y', '执行成功。。。',V_BEGIN_TIME);
2.异常日志:PROC_SAVELOG(V_PROC_NAME, 'N', SQLERRM,V_BEGIN_TIME);
BEGIN
INSERT INTO PROGRAM_EXECUTE_LOG
(PROGRAM_NAME,
IS_SUCCEED,
LOG_DATE,
EXECUTE_MSG,
TIME_CONSUMING,
EXECUTE_BEGINTIME,
EXECUTE_ENDTIME)
VALUES
(V_PROGRAM_NAME,
V_IS_SUCCEED,
SYSDATE,
EXECUTE_MSG,
F_TIMESTAMP_DIFF(SYSTIMESTAMP, V_BEGIN_TIME),
V_BEGIN_TIME,
SYSTIMESTAMP);
COMMIT;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
END;
CREATE OR REPLACE PROCEDURE SYS_PROCESS_ERRMSG(PROC_NAME VARCHAR2,
EXE_MSG CLOB,
ERR_MSG VARCHAR2,
BEGIN_TIME TIMESTAMP,
RESULT OUT VARCHAR2) AS