You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 03:45:05