2014-02-21 31 views
3

我正在嘗試將我的作業的REPEAT_INTERVAL設置爲PL/SQL表達式 - 不幸的是,它不起作用。在Oracle 11g的repeat_interval中使用PL/SQL表達式DBMS_SCHEDULER

我想在這樣的時間間隔內包含CASE表達式,例如,如何在整整一分鐘內開始工作的重複間隔,讓我們在14:17:00說,如果它在每分鐘內運行它在30秒內下一次運行,如果是奇數分鐘運行它開始於下一分鐘,所以這塊它的運行時間表會是什麼樣子:

14:17:00 
14:18:00 
14:18:30 
14:19:00 
14:20:00 
14:20:30 
14:21:00 

等。我試過這些表達式:

trunc(sysdate, 'MI') + CASE WHEN mod(to_number(to_char(sysdate, 'MI')), 2)=0 then (1/24/60/2) else (1/24/60) end case 
SYSTIMESTAMP + CASE WHEN mod(to_number(to_char(sysdate, 'MI')), 2)=0 then INTERVAL '30' SECOND else INTERVAL '60' SECOND end case 

它們都在SQL查詢中工作,但我無法編譯JOB。這樣的PL/SQL表達式應該如何?

另外,有沒有辦法讓JOB在運行時計算下一個運行日期?我也嘗試在每次作業運行時修改開始日期,但沒有成功 - 它看起來像工作在第一次運行時僅使用開始日期一次,即使未來日期的日期更改也不會再次開始。

+2

雖然這當然是一個非常有趣的問題,但我很好奇 - 爲什麼你需要這個?你不能每分鐘都只做一次這項工作嗎? –

+0

這是簡化的情況 - 事實上我需要在每個星期五的工作中排除情況,星期五不是某個月的最後一天,那麼它應該在下個月的第一天運行 - 我認爲在日曆表達中很難實現。或者,我會每天運行工作,並檢查這是否是「正確」的一天,如果是的話,我會運行程序,如果沒有,我不會。 – WojtusJ

+0

這應該可以使用組合的時間表 - 請參閱我的答案。 –

回答

3

至於我可以告訴the documentation,這應該是可能的,如果你

  • 創建兩個時間表;一個用於甚至幾分鐘,一個用於多分鐘
  • 有時間表的一個包括其他
  • 配置你的工作,使用組合時間表

來自實例文檔:

BEGIN 
    dbms_scheduler.create_schedule('embed_sched', repeat_interval => 
    'FREQ=YEARLY;BYDATE=0130,0220,0725'); 
    dbms_scheduler.create_schedule('main_sched', repeat_interval => 
    'FREQ=MONTHLY;INTERVAL=2;BYMONTHDAY=15;BYHOUR=9,17;INCLUDE=embed_sched'); 
END; 
2

我想它有點晚,但比從未更好。您可以使用plssql功能的重複間隔內:

上測試:11.2.0.3.0

讓我們創建功能。 my_schedules.odd_even它將返回CURRENT_DATE +30秒如果當前分鐘甚至1分鐘,如果當前的分鐘是奇數:

CREATE OR REPLACE package my_schedules 
is 
function odd_even(p_date date default sysdate) return date; 
end; 
</code> 
<code> 
CREATE OR REPLACE package body my_schedules 
is 

-- even - 30 seconds 
-- odd - 1 minute; 
function odd_even(p_date date default sysdate) 
return date 
is 
l_ret date; 
l_sec_in_day number := 60*60*24; 
begin 

case mod((to_number(to_char(sysdate,'MI'))) ,2) 
when 0 then 
--- even return 30 seconds 
l_ret:= SYSDATE + 30/l_sec_in_day; 
else 
-- odd return a minute 
l_ret:= SYSDATE + 60/l_sec_in_day; 
end case; 
return l_ret; 
end;`enter code here` 

end; 
/

創建REPEAT_INTERVAL = my_schedules.odd_even作業和使作業:

declare 
    l_action varchar2(2000); 
    l_repeat_interval varchar2(250) := 'my_schedules.odd_even'; 
    l_job_name varchar2(30) := 'TESTING_PLSSQL_SCH'; 
    begin 
    l_action := 'declare dummy number; begin dummy := 1; end;'; 

    dbms_scheduler.create_job(job_name  => '"'|| l_job_name||'"', 
           job_type  => 'plsql_block', 
           job_action  => l_action, 
           start_date  => sysdate, 
           repeat_interval => l_repeat_interval, 
           comments  => 'just a test' 
          ); 

    dbms_scheduler.enable(name => '"'||l_job_name||'"');        
end; 

讓我們檢查的結果在一段時間:

select job_name, actual_start_date from DBA_SCHEDULER_JOB_RUN_DETAILS rd where job_name = 'TESTING_PLSSQL_SCH' order by actual_start_date; 

job_name | actual_start_date 
-------------------------- 
TESTING_PLSSQL_SCH 2016/07/14/ 17:33:36,671977 +03:00 
TESTING_PLSSQL_SCH 2016/07/14/ 17:34:36,007573 +03:00 
TESTING_PLSSQL_SCH 2016/07/14/ 17:35:06,006206 +03:00 
TESTING_PLSSQL_SCH 2016/07/14/ 17:36:06,001652 +03:00 
TESTING_PLSSQL_SCH 2016/07/14/ 17:36:36,005513 +03:00 
TESTING_PLSSQL_SCH 2016/07/14/ 17:37:06,003572 +03:00 
TESTING_PLSSQL_SCH 2016/07/14/ 17:38:06,011409 +03:00 
TESTING_PLSSQL_SCH 2016/07/14/ 17:38:36,011411 +03:00 
TESTING_PLSSQL_SCH 2016/07/14/ 17:39:06,011357 +03:00 
TESTING_PLSSQL_SCH 2016/07/14/ 17:40:06,002623 +03:00 

Oracle數據庫聯機文檔11g第1版(11.1)/數據庫管理/使用時間表:here