DBMS_SCHEDULER.EVALUATE_CALENDAR_STRING
может быть в состоянии сделать это.
Синтаксис, поддерживаемый пакетом, похож на RFC 2445, но не идентичен. Приведенный ниже блок PL / SQL выводит даты на основе календарной строки. Есть некоторые сложности, такие как разбор COUNT=10
, чтобы определить, сколько раз повторить вычисление.
declare
--Test different calendar strings and start dates.
--p_calendar_string varchar2(4000) := 'FREQ=DAILY;INTERVAL=5;';
p_calendar_string varchar2(4000) := 'FREQ=DAILY;INTERVAL=5;COUNT=10';
p_start_date date := timestamp '2019-01-01 00:00:00';
v_next_run_date date;
v_count number;
--Find the COUNT and remove it rom the calendar string, if it exists.
procedure get_and_remove_count(p_calendar_string in out varchar2, p_count out number) is
begin
if lower(p_calendar_string) like '%count%' then
p_count := to_number(regexp_substr(p_calendar_string, 'COUNT=([0-9]+)', 1, 1, null, 1));
p_calendar_string := regexp_replace(p_calendar_string, 'COUNT=[0-9]+;?');
else
p_count := 1;
end if;
end;
begin
get_and_remove_count(p_calendar_string, v_count);
--TEST
--dbms_output.put_line('String: '||p_calendar_string||', count: '||v_count);
--Start with the original date.
v_next_run_date := p_start_date-1/24/60/60;
--Loop through the COUNT and display all dates.
for i in 1 .. v_count loop
dbms_scheduler.evaluate_calendar_string
(
calendar_string => p_calendar_string,
start_date => p_start_date,
return_date_after => v_next_run_date,
next_run_date => v_next_run_date
);
dbms_output.put_line(to_char(v_next_run_date, 'mm/dd/yyyy hh:mi:ss am'));
end loop;
end;
/
Выход:
01/01/2019 12:00:00 am
01/06/2019 12:00:00 am
01/11/2019 12:00:00 am
01/16/2019 12:00:00 am
01/21/2019 12:00:00 am
01/26/2019 12:00:00 am
01/31/2019 12:00:00 am
02/05/2019 12:00:00 am
02/10/2019 12:00:00 am
02/15/2019 12:00:00 am