不久前,做的项目中需要用到定时任务(有两种实现方式:应用程序,数据库。),决定采用数据库的定时任务。关于数据库定时任务的资料,网上有很多文章,但当自己在设计时,并没有仅通过一篇文章就解决问题。于是决定综合网上资料和自己的项目,写一篇oracle数据库自带的job来实现定时任务。
一、定时任务的创建、启动、修改、停止、删除
1、首先需创建一存储过程,然后让定时任务按照设定的时间和时间间隔去执行存储过程。
variable jobno number;——系统会自动分配一个任务号jobno(在此段代码执行完成后,即可显示出jobno,如22) dbms_job.submit(:jobno, ——自动分配的jobno号 ,前边必须有:号 your_procedure;',——需执行的存储过程, ';'不能省略 varchar类型 next_date, ——下次执行时间 date类型 'interval' ,——每次间隔时间,interval以天为单位 varchar类型(interval的参数问题,可参见第二部分)no_parse——可不配置 布尔类型
);
no_parse参数指示此工作在提交时或执行时是否应进行语法分析——TRUE 指示此PL/SQL代码在它第一次执行时应进行语法分析, 而FALSE指示本PL/SQL代码应立即进行语法分析。
上述执行完成后,会显示
PL/SQL procedure successfully completed jobno --------- 22
如:
variable jobno numberb;
begin
dbms_job.submit(:jobno,'proce_receivedOrder;',sysdate,'TRUNC(sysdate) + 1 +14 / (24)'); (每天14点执行)
commit; end;;
2、启动定时任务
执行如下代码:
begin dbms_job.run(22);(此处22为,第一步执行后,显示出来的jobno) commit; end;
3、查看定时任务
select job, next_date, next_sec, failures, broken from user_jobs;
如果信息正确,即创建成功。
4、修改定时任务:
1) 修改要执行的操作: dbms_job.what(jobno, what); 2) 修改下次执行时间:dbms_job.next_date(jobno, next_date); 3) 修改间隔时间:dbms_job.interval(jobno, interval);
如:
begin
dbms_job.next_date (22, TRUNC(sysdate) + 1 +14 / (24) );
commit;
end;
5、停止和删除定时任务
1)停止: dbms_job.broken(jobno, broken, nextdate); –broken为boolean值
如:
begin
dbms_job.broken(22,true,sysdate); commit;
end;
2)删除:dbms_job.remove(jobno);
如:
begin
dbms_job.remove(22); commit;
end;
二、interval参数
1:每分钟执行 TRUNC(sysdate,'mi') + 1/(24*60)
2:每天定时执行
例如:每天的凌晨1点1分1秒执行TRUNC(sysdate) + 1 +1/(24)+1/24/60+1/24/60/60 3:每周定时执行 例如:每周一凌晨1点执行
TRUNC(next_day(sysdate,2))+2/24 --星期一,一周的第二天
TRUNC(next_day(sysdate,'星期一'))+1/24 4:每月定时执行 例如:每月1日凌晨1点执行 TRUNC(LAST_DAY(SYSDATE))+1+1/24 5:每季度定时执行 例如每季度的第一天凌晨1点执行 TRUNC(ADD_MONTHS(SYSDATE,3),'Q') + 1/24 6:每半年定时执行 例如:每年7月1日和1月1日凌晨1点 ADD_MONTHS(trunc(sysdate,'yyyy'),6)+1/24 7:每年定时执行 例如:每年1月1日凌晨1点执行 ADD_MONTHS(trunc(sysdate,'yyyy'), 12)+1/24
8.每个小时的第15分钟运行
例如:8:15,9:15,10:15…:
trunc(sysdate,'hh')+(60+15)/(24*60)。
注:TRUNC(for dates) 函数一些说明
TRUNC函数按一定格式截取日期的值。 语法如下: TRUNC(date[,fmt]) 其中fmt参数可无,默认为截取天 1)按年截取显示当年第一天 select TRUNC(sysdate,'yyyy') from dual 2)按月截尾 显示当年当月第一天 select TRUNC(TO_DATE('2008-03-01 08:23','yyyy-mm-dd hh:mi'),'mm') from dual 3)按日截尾 显示当年当月当日 select TRUNC(TO_DATE('2008-03-01 08:23','yyyy-mm-dd hh:mi'),'dd') from dual 4)按时截尾 显示当年当月当日当时0分0秒 select TRUNC(TO_DATE('2008-03-01 08:23','yyyy-mm-dd hh:mi'),'hh') from dual 5)按分截尾 显示当年当月当日当时当分0秒 select TRUNC(TO_DATE('2008-03-01 08:23','yyyy-mm-dd hh:mi'),'mi') from dual