在写存储过程中一般需要书写过程运行日志,但是工作这么长时间自己从没认真研究过调用日志存储过程的问题。现因项目整合需要做日志监控,才发现日志的重要性:
create or replace procedure bo_dw.sp_sys_log
(
oi_task_id in out integer ,
iv_task_name in varchar2,
iv_table_name in varchar2,
iv_task_sign in varchar2,
ii_task_status in integer ,
iv_task_log in varchar2,
iv_task_pos in varchar2,
iv_task_step_stime in varchar2,
ii_rowcount in integer default null
)
/** HEAD
* @name sp_sys_log
* @caption 日志记录
* @type 日志
* @parameter oi_task_id inout integer 任务ID,任务状态为1时做输出参数,任务状态为0和其它时做输入参?
* @parameter iv_task_name in varchar2 任务名称
* @parameter iv_table_name in varchar2 目标表名
* @parameter iv_task_sign in varchar2 任务标志,任务的统计时间
* @parameter ii_task_status in integer 任务状态,0 程序运行完成,1 程序运行中,其它 出错代码
* @parameter iv_task_log in varchar2 任务日志,正常时为程序运行中或程序运行完成,出错时为出错信息
* @parameter iv_task_pos in varchar2 任务位置,程序中的出错位?
* @parameter ii_rowcount int integer 数据量,可选参数, 缺省值为NULL
* @description 日志记录
* @target vgopsys#tb_sys_log 单条日志表
*/
is
PRAGMA AUTONOMOUS_TRANSACTION;
vv_task_memo varchar2(2000) ;
begin
/** --表结构
create table bo_dw.tb_sys_log
(
task_id number, -- 任务ID
task_name varchar2(30), -- 程序名称
table_name varchar2(30), -- 目标表名
task_sign varchar2(20), -- 任务标志
start_time date, -- 程序开始时间
end_time date, -- 程序结束时间或出错时?
task_status number, -- 任务状态 1开始 0完成 其他失败
task_log varchar2(200), -- 任务日志:正常时为程序运行中或程序运行完成,出错时为出错信息
task_pos varchar2(50), -- 任务位置
task_remark varchar2(2000) -- 任务备注: 任务位置:开始时间yyyymmdd :数据量 (分隔符chr(10))
);
序号
-- Create sequence
create sequence seq_sys_proc_log
maxvalue 9999999999999999999999
start with 1
increment by 1;
*/
/** @description 对不同的任务状态,进行不同的日志处理 */
vv_task_memo :='起止时间:'||iv_task_step_stime||' - '||to_char(sysdate,'dd hh24:mi:ss')||'|'|| '位置:'||iv_task_pos||'|'||'sql记录数:'||ii_rowcount;
if ii_task_status = 1 then
select bo_dw.seq_sys_proc_log.nextval into oi_task_id from dual;
insert into bo_dw.tb_sys_log
(
task_id, -- 任务ID
task_name, -- 程序名称
table_name, -- 目标表名
task_sign, -- 任务标志
start_time, -- 程序开始时间
end_time, -- 程序结束时间或出错时间
task_status, -- 任务状态
task_log, -- 任务日志
task_pos, -- 任务位置
task_memo
)
values
(
oi_task_id ,
iv_task_name ,
iv_table_name ,
iv_task_sign ,
sysdate ,
null ,
1 ,
'程序运行中' ,
iv_task_pos ,
vv_task_memo
);
elsif ii_task_status = 2 then
update bo_dw.tb_sys_log
set task_pos = iv_task_pos,
task_memo= task_memo || chr(10) || vv_task_memo
where task_id = oi_task_id;
elsif ii_task_status = 0 then
update bo_dw.tb_sys_log
set end_time = sysdate,
task_status = 0,
task_log = '程序运行完成',
task_pos = iv_task_pos,
task_memo= task_memo || chr(10) || vv_task_memo
where task_id = oi_task_id;
else
update bo_dw.tb_sys_log
set end_time = sysdate,
task_status = ii_task_status,
task_log = substr(iv_task_log, 1, 200),
task_pos = iv_task_pos /*,
task_memo= task_memo || chr(10) || vv_task_memo*/
where task_id = oi_task_id;
end if;
commit;
end;
这是一个例子,认真琢磨一下还是能明白的。这里在procedure定义中有个PRAGMA AUTONOMOUS_TRANSACTION,百度解释为 自治事务 。对于定义成自治事务的Procedure,实际上相当于一段独立运行的程序段,这段程序不依赖于主程序,也不干涉主程序。
自治事务的特点:
第一,这段程序不依赖于原有Main程序,比如Main程序中有未提交的数据,那么在自治事务中是查找不到的。
第二,在自治事务中,commit或者rollback只会提交或回滚当前自治事务中的DML,不会影响到Main程序中的DML。
关于自治事务解释来源链接:点击打开链接