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的運行時間了。

相關文章
相關標籤/搜索