我正在为我的oracle DB创建一个调度程序这是我到目前为止所做的:
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'CREAZIONE_OCCORRENZE',
job_type => 'STORED_PROCEDURE',
job_action => 'pop_occr_lezione'
start_date => A,
end_date => B,
repeat_interval => 'FREQ=WEEKLY'
enabled => true,
auto_drop => false;
)
END;
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'ASSEGNAZIONE - AULE',
job_type => 'STORED_PROCEDURE',
job_action => 'ass_aule'
start_date => C,
end_date => D,
repeat_interval => 'FREQ=WEEKLY'
enabled => true,
auto_drop => false;
)
END;
/
如您所见,我仍然需要为2个作业设置start_date和end_date。这是相当令人困惑的,我怎么设置:
A =八月的最后一个星期一(每年有效)
B =八月的第一个星期一(一年后的A)
C = A之后的第一个星期日
D = B之后的第一个星期日
我怎么能这样做?
答案 0 :(得分:2)
start_date
和end_date
是固定值,即您不能说“8月的最后一个星期一(每年有效 )”。 start_date
仅用于repeat_interval
的初始值。
例如start_date => TIMESTAMP '2015-03-26 18:00:00', repeat_interval => 'FREQ=WEEKLY'
表示每周一的18:00:00。
end_date
是您的工作已停用的日期。
repeat_interval
为FREQ=MONTHLY;INTERVAL=1;BYMONTH=AUG;BYDAY=-1 MON
repeat_interval
表示“8月的每个第一个星期日”都是FREQ=MONTHLY;INTERVAL=1;BYMONTH=AUG;BYDAY=1 SUN
您可以使用此程序进行验证:
DECLARE
next_run_date TIMESTAMP WITH TIME ZONE;
BEGIN
FOR i IN 1..10 LOOP
DBMS_SCHEDULER.EVALUATE_CALENDAR_STRING('FREQ=MONTHLY;INTERVAL=1;BYMONTH=AUG;BYDAY=-1 MON', NULL, next_run_date, next_run_date);
DBMS_OUTPUT.PUT_LINE ( TO_CHAR(next_run_date, 'yyyy-mm-dd fmDay') );
END LOOP;
next_run_date := NULL;
FOR i IN 1..10 LOOP
DBMS_SCHEDULER.EVALUATE_CALENDAR_STRING('FREQ=MONTHLY;INTERVAL=1;BYMONTH=AUG;BYDAY=1 SUN', NULL, next_run_date, next_run_date);
DBMS_OUTPUT.PUT_LINE ( TO_CHAR(next_run_date, 'yyyy-mm-dd fmDay') );
END LOOP;
END;
2015-08-31 Monday
2016-08-29 Monday
2017-08-28 Monday
2018-08-27 Monday
2019-08-26 Monday
2020-08-31 Monday
2021-08-30 Monday
2022-08-29 Monday
2023-08-28 Monday
2024-08-26 Monday
2015-08-30 Sunday
2016-08-28 Sunday
2017-08-27 Sunday
2018-08-26 Sunday
2019-08-25 Sunday
2020-08-30 Sunday
2021-08-29 Sunday
2022-08-28 Sunday
2023-08-27 Sunday
2024-08-25 Sunday
查看Calendaring Syntax了解更多详情
基于此,您可以创建另一个设置start_date
主要工作的工作,即:
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'SET_START_TIME',
job_type => 'PLSQL_BLOCK',
job_action => 'BEGIN DBMS_SCHEDULER.SET_ATTRIBUTE(''CREAZIONE_OCCORRENZE'', ''START_DATE'', LOCALTIMESTAMP); END;',
repeat_interval => 'FREQ=MONTHLY;INTERVAL=1;BYMONTH=AUG;BYDAY=-1 MON'
enabled => TRUE,
auto_drop => FALSE);
END;
答案 1 :(得分:0)
您可以使用此查询来获取信息...然后您只需将值填充到dbms_scheduler中。如果您需要每年执行此操作,则可能需要使用动态sql来调用调度程序。
with w_current as (
select add_months(trunc(sysdate,'YYYY'),7+12) aug1,
last_day(add_months(trunc(sysdate,'YYYY'),7)) aug31
from dual
),
w_mondays as (
select aug1+mod(9-to_char(aug1,'D'),7) first_mon_aug,
aug31+mod(8-to_char(aug31,'D'),7)-6 last_mon_aug
from w_current
)
select first_mon_aug, last_mon_aug,
first_mon_aug+6 first_sun_after_A,
last_mon_aug+6 first_sun_after_B
from w_mondays;
答案 2 :(得分:0)
我很困惑,你在周一和周日混合(2015-07-12是周一,而不是周日),你改变了问题的要求。
据我了解您的日程安排而言,为了简化,您希望每周一运行CREAZIONE_OCCORRENZE
除了从7月的第二个星期一到最后一个星期一八月"。工作ASSEGNAZIONE_AULE
总是在五天之后运行。
然后你可以处理排除。它应该是这个:
BEGIN
DBMS_SCHEDULER.CREATE_SCHEDULE (
schedule_name => 'MONDAY_AUGUST',
repeat_interval => 'FREQ=MONTHLY;INTERVAL=1;BYMONTH=AUG;BYDAY=-5 MON,-4 MON,-3 MON,-2 MON');
DBMS_SCHEDULER.CREATE_SCHEDULE (
schedule_name => 'MONDAY_JULY',
repeat_interval => 'FREQ=MONTHLY;INTERVAL=1;BYMONTH=JUL;BYDAY=2 MON,3 MON,4 MON,5 MON');
DBMS_SCHEDULER.CREATE_SCHEDULE (
schedule_name => 'MONDAYS',
repeat_interval => 'FREQ=WEEKLY;INTERVAL=1;BYDAY=MON;EXCLUDE=MONDAY_AUGUST,MONDAY_JULY');
DBMS_SCHEDULER.CREATE_SCHEDULE (
schedule_name => 'SUNDAYS',
repeat_interval => 'MONDAYS+OFFSET:6D');
END;
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'CREAZIONE_OCCORRENZE',
job_type => 'STORED_PROCEDURE',
job_action => 'pop_occr_lezione'
start_date => NULL,
end_date => NULL,
repeat_interval => 'MONDAYS'
enabled => true,
auto_drop => false);
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'ASSEGNAZIONE - AULE',
job_type => 'STORED_PROCEDURE',
job_action => 'ass_aule'
start_date => NULL,
end_date => NULL,
repeat_interval => 'SUNDAYS'
enabled => true,
auto_drop => false);
END;
/
用于测试计划的PL / SQL块:
DECLARE
next_run_date TIMESTAMP WITH TIME ZONE;
BEGIN
next_run_date := NULL;
DBMS_OUTPUT.PUT_LINE ('Excluded Mondays in August' );
FOR i IN 1..10 LOOP
DBMS_SCHEDULER.EVALUATE_CALENDAR_STRING('MONDAY_AUGUST', NULL, next_run_date, next_run_date);
DBMS_OUTPUT.PUT_LINE ( TO_CHAR(next_run_date, 'yyyy-mm-dd wTH fmDay') );
END LOOP;
next_run_date := NULL;
DBMS_OUTPUT.PUT_LINE ('Excluded Mondays in July' );
FOR i IN 1..10 LOOP
DBMS_SCHEDULER.EVALUATE_CALENDAR_STRING('MONDAY_JULY', NULL, next_run_date, next_run_date);
DBMS_OUTPUT.PUT_LINE ( TO_CHAR(next_run_date, 'yyyy-mm-dd wTH fmDay') );
END LOOP;
next_run_date := NULL;
DBMS_OUTPUT.PUT_LINE ('Executions Job 1' );
FOR i IN 1..150 LOOP
DBMS_SCHEDULER.EVALUATE_CALENDAR_STRING('MONDAYS', NULL, next_run_date, next_run_date);
IF TO_CHAR(next_run_date, 'IW') BETWEEN 25 AND 38 THEN -- avoid excessive output
DBMS_OUTPUT.PUT_LINE ( TO_CHAR(next_run_date, 'yyyy-mm-dd wTH fmDay') );
END IF;
END LOOP;
next_run_date := NULL;
DBMS_OUTPUT.PUT_LINE ('Executions Job 2' );
FOR i IN 1..150 LOOP
DBMS_SCHEDULER.EVALUATE_CALENDAR_STRING('SUNDAYS', NULL, next_run_date, next_run_date);
IF TO_CHAR(next_run_date, 'IW') BETWEEN 25 AND 38 THEN -- avoid excessive output
DBMS_OUTPUT.PUT_LINE ( TO_CHAR(next_run_date, 'yyyy-mm-dd wTH fmDay') );
END IF;
END LOOP;
END;
Excluded Mondays in August
2015-08-03 1st Monday
2015-08-10 2nd Monday
2015-08-17 3rd Monday
2015-08-24 4th Monday
2016-08-01 1st Monday
2016-08-08 2nd Monday
2016-08-15 3rd Monday
2016-08-22 4th Monday
2017-08-07 1st Monday
2017-08-14 2nd Monday
Excluded Mondays in July
2015-07-13 2nd Monday
2015-07-20 3rd Monday
2015-07-27 4th Monday
2016-07-11 2nd Monday
2016-07-18 3rd Monday
2016-07-25 4th Monday
2017-07-10 2nd Monday
2017-07-17 3rd Monday
2017-07-24 4th Monday
2017-07-31 5th Monday
Executions Job 1
2015-06-15 3rd Monday
2015-06-22 4th Monday
2015-06-29 5th Monday
2015-07-06 1st Monday
2015-08-31 5th Monday
2015-09-07 1st Monday
2015-09-14 2nd Monday
2016-06-20 3rd Monday
2016-06-27 4th Monday
2016-07-04 1st Monday
2016-08-29 5th Monday
2016-09-05 1st Monday
2016-09-12 2nd Monday
2016-09-19 3rd Monday
2017-06-19 3rd Monday
2017-06-26 4th Monday
2017-07-03 1st Monday
2017-08-28 4th Monday
2017-09-04 1st Monday
2017-09-11 2nd Monday
2017-09-18 3rd Monday
2018-06-18 3rd Monday
2018-06-25 4th Monday
2018-07-02 1st Monday
Executions Job 2
2015-06-21 3rd Sunday
2015-06-28 4th Sunday
2015-07-05 1st Sunday
2015-07-12 2nd Sunday
2015-09-06 1st Sunday
2015-09-13 2nd Sunday
2015-09-20 3rd Sunday
2016-06-26 4th Sunday
2016-07-03 1st Sunday
2016-07-10 2nd Sunday
2016-09-04 1st Sunday
2016-09-11 2nd Sunday
2016-09-18 3rd Sunday
2016-09-25 4th Sunday
2017-06-25 4th Sunday
2017-07-02 1st Sunday
2017-07-09 2nd Sunday
2017-09-03 1st Sunday
2017-09-10 2nd Sunday
2017-09-17 3rd Sunday
2017-09-24 4th Sunday
2018-06-24 4th Sunday
2018-07-01 1st Sunday
2018-07-08 2nd Sunday