前几天,公司的job调度出现了问题,由于权限管的严,没有查看oracle 一些重要的数据字典,后面联系DBA,是由于数据库切换到备机时,参数设置不对,导致db job没有正常调度。
今天刚好有时间,想总结下 oracle 的定时任务,写的不好的地方,请多多指教!
--1.先检查 oracle job 两个重要参数 job_queue_processes 和 aq_tm_processes
SQL> show parameter job_queue_processes;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
job_queue_processes integer 0
SQL> show parameter aq_tm_processes;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
aq_tm_processes integer 0
--2.新建一个序列,作为数据来源
-- Create sequence
create sequence s_seq
minvalue 0
maxvalue 10000
start with 1
increment by 1
order;
--3.新建一张测试表
--create table
create table t_job(
id number,
record_time date
);
--4.创建一个存储过程;
create or replace procedure proc_test_job as
begin
insert into t_job
(id,record_time)
select s_seq.nextval,sysdate from dual;
commit;
end proc_test_job;
/
--5.创建一个定时任务
declare
job_number number;
cursor job_cursor is select * from user_jobs where what like '%proc_test_job%';
begin
for x in job_cursor loop
job_number:=x.job;
sys.dbms_job.remove(job_number);
end loop;
commit;
-- Call the procedure
sys.dbms_job.submit(job => job_number, --out参数,job编号
what => 'proc_test_job;', --注意有分号
next_date => sysdate + 5/(24*60), --下一个 5分钟执行
interval => 'trunc(sysdate,''mi'')+1/(24*60)' --每隔一分钟执行
);
commit;
end;
/
--6.查看job的信息
select t.JOB, t.NEXT_DATE, t.WHAT, t.INTERVAL, t.*
from user_jobs t
where t.WHAT like '%proc_test_job%';
--7.设置 第 1步中的两个参数
SQL> alter system set job_queue_processes = 10 scope = both;
System altered
SQL> alter system set aq_tm_processes = 1 scope = both;
System altered
--8.查看job的信息以及目标表的数据,从以下查看,确实是每隔1分中执行一次
这样就完成了一个 定时任务的配置了。
关于 job_queue_processes 详细介绍,可以参考 http://blog.sina.com.cn/s/blog_62defbef0101opv0.html 。
aq_tm_processes 参数的讲解,可以参考 http://blog.sina.com.cn/s/blog_61cd89f60102e9lc.html,在此谢谢这两位作者。
在实际工作,由于业务的需要,比如公司经常做活动,那可能会经常调整db job 调度时间。下面讲解一些在工作当中操作job的sp
1.要修改 job 的下次启动时间;
begin
-- Call the procedure
sys.dbms_job.next_date(job => :job, --job 是入参,对应的是 user_jobs 中的 job字段信息
next_date => :next_date); --job 下次启动时间
end;
2.要停止调度 job;
begin
-- Call the procedure
sys.dbms_job.broken(job => :job,
broken => broken,
next_date => :next_date); -- next_date(指定某一时刻停止) sysdate(立刻停止)
end;
3.删除job
begin
-- Call the procedure
sys.dbms_job.remove(job => :job);
end;
4.启动job
begin
-- Call the procedure
sys.dbms_job.run(job => :job, force => force);
end;
5.修改要执行的job
begin
-- Call the procedure
sys.dbms_job.what(job => :job,
what => :what);
end;
--6.修改job的执行间隔
begin
-- Call the procedure
sys.dbms_job.interval(job => :job,
interval => :interval);
end;
--一些常用的时间设置
1:每分钟执行
Interval => TRUNC(sysdate,'mi') + 1/ (24*60) --每分钟执行
interval => 'sysdate+1/(24*60)' --每分钟执行
interval => 'sysdate+1' --每天
interval => 'sysdate+1/24' --每小时
interval => 'sysdate+2/24*60' --每2分钟
interval => 'sysdate+30/24*60*60' --每30秒
2:每天定时执行
Interval => TRUNC(sysdate+1) --每天凌晨0点执行
Interval => TRUNC(sysdate+1)+1/24 --每天凌晨1点执行
Interval => TRUNC(SYSDATE+1)+(8*60+30)/(24*60) --每天早上8点30分执行
3:每周定时执行
Interval => TRUNC(next_day(sysdate,'星期一'))+1/24 --每周一凌晨1点执行
Interval => TRUNC(next_day(sysdate,1))+2/24 --每周一凌晨2点执行
4:每月定时执行
Interval =>TTRUNC(LAST_DAY(SYSDATE)+1) --每月1日凌晨0点执行
Interval =>TRUNC(LAST_DAY(SYSDATE))+1+1/24 --每月1日凌晨1点执行
5:每季度定时执行
Interval => TRUNC(ADD_MONTHS(SYSDATE,3),'q') --每季度的第一天凌晨0点执行
Interval => TRUNC(ADD_MONTHS(SYSDATE,3),'q') + 1/24 --每季度的第一天凌晨1点执行
Interval => TRUNC(ADD_MONTHS(SYSDATE+ 2/24,3),'q')-1/24 --每季度的最后一天的晚上11点执行
6:每半年定时执行
Interval => ADD_MONTHS(trunc(sysdate,'yyyy'),6)+1/24 --每年7月1日和1月1日凌晨1点
7:每年定时执行
Interval =>ADD_MONTHS(trunc(sysdate,'yyyy'),12)+1/24 --每年1月1日凌晨1点执行