如何验证Oracle调度作业是否在上一作业完成前发起请求?
验证作业是否在上一作业完成前发起请求的SQL查询方案
看起来你已经有了一个不错的开头,我来帮你补全并优化这个查询,实现你想要的验证逻辑——检查当前作业的请求启动时间是否早于上一次作业的完成时间(上一次作业的ACTUAL_START_DATE + RUN_DURATION)。
完整查询语句
WITH delay_in_start AS ( SELECT LOG_ID, LOG_DATE, OWNER, JOB_NAME, REQ_START_DATE, ACTUAL_START_DATE, RUN_DURATION, -- 按作业分组,请求启动时间倒序编号,最新的为RN=1,上一次为RN=2 ROW_NUMBER() OVER (PARTITION BY JOB_NAME ORDER BY REQ_START_DATE DESC) RN FROM DBA_SCHEDULER_JOB_RUN_DETAILS t ) SELECT A.JOB_NAME, -- 当前作业的请求启动时间 CAST(A.REQ_START_DATE AS DATE) AS CURRENT_REQ_START, -- 上一次作业的完成时间(实际启动+运行时长) CAST(B.ACTUAL_START_DATE + B.RUN_DURATION AS DATE) AS PREV_JOB_COMPLETION, -- 计算时间差:上一次完成时间 - 当前请求启动时间 (B.ACTUAL_START_DATE + B.RUN_DURATION) - A.REQ_START_DATE AS TIME_DIFF, -- 直接给出判断结果 CASE WHEN (B.ACTUAL_START_DATE + B.RUN_DURATION) < A.REQ_START_DATE THEN '上一作业完成后发起请求' ELSE '上一作业完成前发起请求' END AS VALIDATION_RESULT FROM delay_in_start A -- 关联同一作业的上一次运行记录 JOIN delay_in_start B ON A.JOB_NAME = B.JOB_NAME AND A.RN = 1 -- 当前作业取最新的记录(RN=1) AND B.RN = 2; -- 上一次作业取倒数第二个记录(RN=2)
关键逻辑说明
- CTE部分:通过
ROW_NUMBER()窗口函数给每个作业的运行记录按请求启动时间降序编号,这样RN=1代表该作业最近一次的运行记录,RN=2代表上一次的运行记录。 - 关联逻辑:将同一作业的当前记录(RN=1)和上一次记录(RN=2)关联,便于对比时间。
- 时间差计算:
B.ACTUAL_START_DATE + B.RUN_DURATION得到上一次作业的实际完成时间,用这个时间减去当前作业的REQ_START_DATE:- 如果结果为负数,说明当前作业的请求启动时间早于上一次作业的完成时间,也就是你要验证的「在上一作业完成前发起请求」的情况;
- 如果结果为正数或0,说明当前作业是在上一作业完成后才发起的请求。
- CASE判断:直接生成可读性更强的验证结果,不用自己计算时间差判断。
注意事项
- 这个查询只会返回有至少两次运行记录的作业,如果某个作业只运行过一次,不会出现在结果集中。
- 确保
RUN_DURATION是Oracle支持的INTERVAL类型(比如INTERVAL DAY TO SECOND),这样和ACTUAL_START_DATE(DATE类型)相加才会得到正确的完成时间。如果RUN_DURATION是其他格式(比如秒数),需要先转换为INTERVAL再进行计算。
内容的提问来源于stack exchange,提问作者Pooja
相关产品推荐
相关产品推荐

