基于@Rene 的回答,这可以扩展到一般(通用?)解决方案:
CREATE OR REPLACE FUNCTION recurring_dates (p_year IN NUMBER, p_rule IN VARCHAR)
RETURN dbms_stats.datearray PIPELINED
AS
start_dt DATE;
last_dt DATE;
next_dt DATE;
BEGIN
start_dt := to_date(to_char(p_year,'fm0000')||'01-01','YYYY-MM-DD');
last_dt := to_date(to_char(p_year,'fm0000')||'12-31','YYYY-MM-DD');
LOOP
dbms_scheduler.evaluate_calendar_string(
calendar_string => p_rule,
start_date => start_dt,
return_date_after => start_dt,
next_run_date => next_dt);
EXIT WHEN next_dt > last_dt;
PIPE ROW (next_dt);
start_dt := next_dt;
END LOOP;
END recurring_dates;
/
您可以在DBMS_SCHEDULER
-Syntax 中为该函数提供一个日历字符串,它将返回匹配的日期。
@rcmuthu786 的最后一个星期四:
SELECT * FROM TABLE(recurring_dates (2013, 'FREQ=MONTHLY;BYDAY=-1 THU'));
2013-01-31
2013-02-28
2013-03-28
2013-04-25
2013-05-30
...
或者,每个月的第二个星期三:
SELECT * FROM TABLE(recurring_dates (2013, 'FREQ=MONTHLY;BYDAY=2 WED'));
2013-01-09
2013-02-13
2013-03-13
2013-04-10
...
等等等等……