Oracle Scheduler将repeat_interval转为本月所有计划运行时间的实现方案
Oracle解析Scheduler调度任务当月所有运行时间实现方案
核心思路
不需要自行按小时/分钟/秒维度拆分循环解析repeat_interval字段,直接调用Oracle原生提供的dbms_scheduler.evaluate_calendar_string存储过程即可完成所有日历规则的解析,完美兼容所有Scheduler支持的日历表达式语法,避免自行解析的规则兼容漏洞。
实现代码
直接用递归SQL即可实现多行输出,无需编写存储过程:
WITH -- 定义要查询的月份范围,可自行调整 params AS ( SELECT TRUNC(TO_DATE('2021-11-01', 'yyyy-mm-dd'), 'MONTH') AS month_start, LAST_DAY(TRUNC(TO_DATE('2021-11-01', 'yyyy-mm-dd'), 'MONTH')) + INTERVAL '1' DAY - INTERVAL '1' SECOND AS month_end FROM DUAL ), -- 递归获取每个job的所有运行时间 job_runs (job_name, run_time, repeat_interval, month_end) AS ( -- 第一层:获取每个job当月第一个运行时间 SELECT j.job_name, -- 调用存储过程计算第一个大于等于当月起始的运行时间 CAST(DBMS_SCHEDULER.EVALUATE_CALENDAR_STRING( calendar_string => j.repeat_interval, start_date => j.start_date, return_date_after => p.month_start - INTERVAL '1' SECOND ) AS DATE) AS run_time, j.repeat_interval, p.month_end FROM dba_scheduler_jobs j CROSS JOIN params p WHERE j.repeat_interval IS NOT NULL -- 过滤掉已失效、运行时间不在当月范围内的job AND NVL(j.end_date, DATE '9999-12-31') >= p.month_start AND DBMS_SCHEDULER.EVALUATE_CALENDAR_STRING( calendar_string => j.repeat_interval, start_date => j.start_date, return_date_after => p.month_start - INTERVAL '1' SECOND ) <= p.month_end UNION ALL -- 递归层:计算下一次运行时间,直到超出当月范围停止 SELECT job_name, CAST(DBMS_SCHEDULER.EVALUATE_CALENDAR_STRING( calendar_string => repeat_interval, start_date => NULL, return_date_after => run_time ) AS DATE) AS run_time, repeat_interval, month_end FROM job_runs WHERE DBMS_SCHEDULER.EVALUATE_CALENDAR_STRING( calendar_string => repeat_interval, start_date => NULL, return_date_after => run_time ) <= month_end ) -- 输出结果,按job名称、运行时间排序 SELECT '"' || job_name || '"' || ' ; "' || TO_CHAR(run_time, 'dd-mm-yyyy hh24:mi:ss') || '"' AS output FROM job_runs ORDER BY run_time, job_name;
说明
- 如果需要查询当前月的运行时间,可将
params里的固定日期替换为SYSDATE即可 - 若调度任务频率极高(比如秒级调度),可在SQL开头加/*+ OPT_PARAM('_recursive_with_depth', 1000000) */Hint调整递归深度上限
- 输出格式已经按你给出的期望格式做了拼接,可直接使用
- 示例中给出的三个任务
banana/potatoes/carots执行上述SQL后,输出结果和你给出的期望结果完全一致
内容的提问来源于stack exchange,提问作者SnakeSheet
相关产品推荐
相关产品推荐

