文章目录
0、参考资料&注意事项
Oracle Database Administrator’s Guide -> Support for DBMS_JOB in Release 11gR2
注意事项:
修改完dbms_job的属性后记着要commit
dbms_job说明:
dbms_job是个pl/sql包,可以让你创建oracle job,oracle 10g以后被scheduler取代,10g以上版本中保留dbms_job功能仅仅是为了向前兼容,就像exp/imp一样。
1、dbms_jobs相关视图和参数
相关视图:
dba_jobs_running
dba_jobs
相关参数:
初始化相关的参数:job_queue_process
建议最大job进程数不要超过1000,oracle11g默认job队列进程数为1000.
查看所有的 JOB &查询正在运行的JOB
select * from dba_jobs;
select job,what,to_char(last_date,'yyyy-mm-dd HH24:mi:ss'),to_char(next_date,'yyyy-mm-dd HH24:mi:ss'),interval from dba_jobs ;
select * from dba_jobs_running;
字段说明:
job : job
what : 执行的存储过程或SQL语句
failures : 失败次数
broken : 状态
2、dbms_job管理
dbms_job停止启动案例
--A层库查询出dbms_job的停止脚本
select 'exec dbms_ijob.broken('||job||',true);' from dba_jobs where broken='N';
--A层库查询出dbms_job的启动脚本
select 'exec dbms_ijob.broken('||job||',false);' from dba_jobs where broken='N';
2.1、创建 DBMS_JOB
使用以下语句:
VARIABLE jobno number;
begin
DBMS_JOB.SUBMIT(
:jobno, --job号,ORACLE自动分配
'your_procedure;', --执行的存储过程或SQL语句,';'不能省略
next_date, --下次执行时间
'interval' --每次间隔时间,以天为单位
);
commit;
end;
创建dbms_job案例:
为了示范,先创建一张简单的表:
CREATE TABLE T_TIME(JOB_TIME DATE not null);
- 每分种为 T_TIME 表插入一条数据:
VARIABLE jobno number;
begin
DBMS_JOB.SUBMIT(
:jobno,
'insert into T_TIME values (sysdate);',
Sysdate,
'sysdate+1/24/60'
);
commit;
end;
- 每天删除前一天的数据:
VARIABLE jobno number;
begin
DBMS_JOB.SUBMIT(
:jobno,
'delete T_TIME where JOB_TIME < sysdate-1;',
Sysdate,
'sysdate+1/24'
);
commit;
end;
- 特殊情况(sql语句中包含单引号)
declare
job_id pls_integer;
begin
sys.dbms_job.submit(job => job_id,
what => 'insert into sess_lgwr SELECT sysdate check_time,SECONDS_IN_WAIT,BLOCKING_SESSION, PROGRAM FROM GV$SESSION@TEST_CAS1 WHERE PROGRAM LIKE ''%LGWR%'';',
next_date =>sysdate,
interval => 'sysdate+3/24/60/60'
);
commit;
end;
2.2、启停\修改dbms_job
停止 JOB
BEGIN DBMS_JOB.BROKEN(jobno, TRUE); END;
参数 jobno 为对应的JOB号,如 BEGIN DBMS_JOB.BROKEN(2, TRUE); END;
启动 JOB
BEGIN DBMS_JOB.run(jobno); END;
或者
exec dbms_job.broken(1,false);
commit;
删除 JOB
BEGIN DBMS_JOB.remove(jobno); END;
修改 JOB
修改运行的内容
BEGIN DBMS_JOB.what(
jobno, --对应的job号
'your_procedure;' --执行的存储过程或SQL语句,';'不能省略
);
END;
修改时间间隔
BEGIN DBMS_JOB.interval(
jobno, --对应的job号
'interval' --每次间隔时间,以天为单位
); END;
修改下一次执行时间
exec dbms_ijob.next_date(22,to_date('2019-09-15 04:00:00','yyyy-mm-dd hh24:mi:ss'));
BEGIN DBMS_JOB.next_date(
jobno, --对应的job号
next_date, --下次执行时间
); END;
2.3、非job owner用户管理job
不是job的owner的用户delete,remove,broken 一个job时,会报错:ORA-23421: job number XXXX is not a job in the job queue
只有job的owner才能够对job进行修改变更,比如下面的脚本所示:
sys@im1>select job, what, log_user, priv_user,broken from dba_jobs where job=275;
JOB WHAT LOG_USER PRIV_USER B
---------- ---------------------------------------- ---------- ---------- -
275 WEB_SMS.cleanAppBuffer; SYSTEM SYSTEM N
system@im1>exec DBMS_JOB.broken(295,false);
PL/SQL procedure successfully completed.
system@im1>exec DBMS_JOB.broken(295,true);
PL/SQL procedure successfully completed.
system@im1>commit;
Commit complete.
system@im1>select job, log_user, priv_user,broken from dba_jobs where job in (295);
JOB LOG_USER PRIV_USER B
---------- ---------- ---------- -
295 SYSTEM SYSTEM Y
如果登录的用户不是job的owner,比如sys用户:
sys@im1>exec DBMS_IJOB.broken(275,true);
PL/SQL procedure successfully completed.
sys@im1>select job, what, log_user, priv_user,broken from dba_jobs where job=275;
JOB WHAT LOG_USER PRIV_USER B
---------- ---------------------------------------- ---------- ---------- -
275 WEB_SMS.cleanAppBuffer; SYSTEM SYSTEM Y
sys@im1>exec DBMS_IJOB.broken(275,false);
PL/SQL procedure successfully completed.
3、关于 interval 的一些设置技巧
关于job运行时间
1:每分钟执行
'sysdate+1/24/60'
Interval => TRUNC(sysdate,'mi') + 1/(24*60)
2:每天定时执行
例如:每天的凌晨1点执行
Interval => TRUNC(sysdate) + 1 +1/(24)
3:每周定时执行
例如:每周一凌晨1点执行
Interval => TRUNC(next_day(sysdate,'星期一'))+1/24
4:每月定时执行
例如:每月1日凌晨1点执行
Interval =>TRUNC(LAST_DAY(SYSDATE))+1+1/24
5:每季度定时执行
例如每季度的第一天凌晨1点执行
Interval => TRUNC(ADD_MONTHS(SYSDATE,3),'Q') + 1/24
6:每半年定时执行
例如:每年7月1日和1月1日凌晨1点
Interval => ADD_MONTHS(trunc(sysdate,'yyyy'),6)+1/24
7:每年定时执行
例如:每年1月1日凌晨1点执行
Interval =>ADD_MONTHS(trunc(sysdate,'yyyy'), 12)+1/24
job的运行频率设置
1.每天固定时间运行,比如早上8:10分钟:Trunc(Sysdate+1) + (8*60+10)/24*60
2.Toad中提供的:
每天:trunc(sysdate+1)
每周:trunc(sysdate+7)
每月:trunc(sysdate+30)
每个星期日:next_day(trunc(sysdate),'星期日')
每天6点:trunc(sysdate+1)+6/24
半个小时:sysdate+30/(24*60)
3.每个小时的第15分钟运行,比如:8:15,9:15,10:15…:trunc(sysdate,'hh')+(60+15)/(24*60)。
描述 INTERVAL参数值
每天午夜12点 'TRUNC(SYSDATE + 1)'
每天早上8点30分 'TRUNC(SYSDATE + 1) + (8*60+30)/(24*60)'
每星期二中午12点 'NEXT_DAY(TRUNC(SYSDATE ), ''TUESDAY'' ) + 12/24'
每个月第一天的午夜12点 'TRUNC(LAST_DAY(SYSDATE ) + 1)'
每个季度最后一天的晚上11点 'TRUNC(ADD_MONTHS(SYSDATE + 2/24, 3 ), 'Q' ) -1/24'
每星期六和日早上6点10分 'TRUNC(LEAST(NEXT_DAY(SYSDATE, ''SATURDAY"), NEXT_DAY(SYSDATE, "SUNDAY"))) + (6×60+10)/(24×60)'