oracle中准确控制job的下次运行时间(next date)

用过ORACLE的JOB的朋友也许都可以感受到它的强大,和JAVA中的quartz有殊途同归之妙,能够少了不少的重复劳动;可是也会有许多问题,就是执行时间段和执行时间比较不容易肯定。 这其实都是咱们还不熟悉JOB的interval形成的。sql

 

    我碰到过几种用JOB的状况,从简到烦说三种:数据库

 

    1。最简单的,一个隔一段时间执行一次,没有其它限制。函数

          interval: sysdate+2       每隔2天执行一次spa

                     sysdate+1/2     每隔12小时执行一次code

                     sysdate+3/1440  每隔 3 分钟执行一次blog

    2。简单的定时执行。get

          interval:  trunc(sysdate+1)+1/3 天天的8点运行io

 

    3。要定时间段执行的。function

          interval: case when to_number(to_char(sysdate,'hh24'))>=8 and to_number(to_char(sysdate,'hh24'))<=20 then sysdate+15/1440 else trunc(sysdate+1)+1/3 endclass

                   天天的8点到20点之点,每隔15分钟运行一次。

                    case when to_number(to_char(sysdate,'mm'))>=6 and to_number(to_char(sysdate,'mm'))<=10 then trunc(sysdate+30) else trunc(sysdate+1)+1/6 end

                   6-10月份,每隔30天的凌晨开始运行,其他月份每隔一天早上4点运行

 

    4。最困难的,每次运行都要求在指定时间

         如3第一个,要求不只是在天天的8点到20点之点,每隔15分钟运行一次,并且都要在0分,15分,30分,45分运行。

         困难在ORACLE的JOB机制,它的下次运行时间是在你的任务跑完之后才计算的。 你的任务或多或少都会花些时间,这就致使下次运行时间不许。 好比,第一次运行是在 8:00:00,任务运行时间 10秒,那么下次的运行时间就是变成了 8:15:10(由于当时的sysdate+15/1440就是8:15:10),而不是但愿的 8:15:00,这样多跑几回,就会形成很大的出入。

 

         解决办法仍是用job的interval,它不只支持象 3 这样的sql语句,并且还支持函数,这样功能就强了。

    写一个函数 fn_get_myjob_interval

create or replace function fn_get_myjob_interval(now date) return date is
  Result date;
  v_n_min number;
  v_n_hour number;
  v_n_all date;
begin
   v_n_min:= to_number(to_char(now,'mi'));
   v_n_hour:=to_number(to_char(now,'hh24'));
  
   if v_n_hour>=20 then
      result:=trunc(sysdate+1)+1/3;
   else
      v_n_all:=trunc(sysdate);
      if v_n_min>=0 and v_n_min<15 then        
         result:=v_n_all+(v_n_hour*60+15)/1440;
      elsif v_n_min>=15 and v_n_min<30 then
         result:=v_n_all+(v_n_hour*60+30)/1440;
      elsif v_n_min>=30 and v_n_min<45 then
         result:=v_n_all+(v_n_hour*60+45)/1440;
      else
         result:=v_n_all+(v_n_hour+1)*60/1440;
      end if;
   end if;
  return(Result);
end fn_get_so2do_job_interval;

而后在可视界面或语句中,指定,interval : fn_get_myjob_interval(sysdate) 就大功告成了。

 若是可行的话(间隔不是很短),还可能预先把每次运行的时间放在数据库里,用函数来读,这样就能够动态控制JOB的运行时间了。

相关文章
相关标签/搜索