有时候我们可以通过Oracle的jobs来定时执行一些存储过程程序,以下是一个例子:
begin
sys.dbms_job.submit(job => :job,
what => 'proc_banping;',
next_date => to_date('15-09-2009 04:00:00', 'dd-mm-yyyy hh24:mi:ss'),
interval => 'sysdate+1');
commit;
end;
/
其中next_date是下次执行的时间,而interval则是时间间隔。
可通过user_jobs或dba_jobs视图查看定时任务的执行情况。
这2个视图中的TOTAL_TIME列的含义是:
Total wallclock time spent by the system on this job, in seconds
第一次执行后的该列的值就是该任务的实际运行实际,以后就是累计时间了。
这里interval 设置为sysdate+1是有问题的,Oracle会取上次开始执行的时间加上一天作为下次开始执行任务的时间,也就是说每次的开始执行时间是受上一次任务的开始时间控制的。
user_jobs视图的next_date信息是Oracle每次运行任务结束后自动修改的,修改的算法就是interval+this_date+this_sec,有时候任务因为某种原因延迟了,这里的next_date就会在上次运行的时间的基础上加一天,从而,偏离了规划的时间,这是我们不希望看到的,可以通过以下命令指定下次运行的时间,但根据上边的算法,这个命令不一定生效:
SQL> exec dbms_job.next_date(22,to_date('2009-09-15 04:00:00','yyyy-mm-dd hh24:mi:ss'));
PL/SQL procedure successfully completed
SQL> commit;
Commit complete
这时我们可以指定interval来设置具体的时间,比如上边的例子,设置为每天凌晨4点执行,而不管上次的运行时间,可以将interval设置为:trunc(SYSDATE)+1+4/24,这是比较合理的做法。