これらのトリッキーな相対日付の問題に対する便利な手法の 1 つは、DBMS_Schedular カレンダー構文を使用することです。
DBMS_Scheduler には、複雑なカレンダー仕様に適した非常に包括的なカレンダー構文があり (慣れれば)、Evaluate_Calendar_String 関数は、指定された日付の後にスケジュール仕様を満たす次のタイムスタンプを返します。
コードは次のとおりです。
create or replace type timestamp_table_type
is
table of timestamp;
/
create or replace function
list_of_dates (
calendar_string varchar2,
start_date TIMESTAMP WITH TIME ZONE,
stop_date TIMESTAMP WITH TIME ZONE)
return
timestamp_table_type
pipelined
is
l_return_date_after TIMESTAMP WITH TIME ZONE := start_date - interval '1' second;
l_next_run_date TIMESTAMP WITH TIME ZONE;
begin
loop
DBMS_SCHEDULER.EVALUATE_CALENDAR_STRING(
calendar_string => list_of_dates.calendar_string,
start_date => list_of_dates.start_date,
return_date_after => l_return_date_after,
next_run_date => l_next_run_date);
exit when list_of_dates.l_next_run_date > coalesce(list_of_dates.stop_date,date '9999-12-31');
pipe row (list_of_dates.l_next_run_date);
list_of_dates.l_return_date_after := list_of_dates.l_next_run_date;
end loop;
end;
/
毎月第 3 金曜日は次のようになると思います。
begin
dbms_scheduler.create_schedule(
schedule_name => 'THIRD_THU_OF_EVERY_MONTH',
repeat_interval => 'FREQ=MONTHLY;BYDAY=5;BYSETPOS=3');
end;
/
select *
from table(
list_of_dates(
'THIRD_THU_OF_EVERY_MONTH',
sysdate ,
null));
残念ながら、これをテストするのに便利な Oracle システムが手元にありません。