获取连续3次失败的作业列表

时间:2019-03-29 19:40:19

标签: sql oracle

failure_count在Oracle中不可靠,因此我正在寻找要查询SYS.ALL_SCHEDULER_JOB_RUN_DETAILS的SQL。

对于初学者来说,这是包含运行详细信息的表,在此查询中,我添加了一个硬编码的作业名称,仅获得最后3次运行。

SELECT * 
FROM SYS.ALL_SCHEDULER_JOB_RUN_DETAILS 
WHERE JOB_NAME = 'MY JOB' 
ORDER BY LOG_ID 
FETCH FIRST 3 ROWS ONLY

我想做的是将此与查询ALL_SCHEDULER_JOBS结合起来,可以对每个作业进行查询,检查最后3次运行,如果所有3个的STATUS'FAILED',然后返回。

我只是不确定如何执行此操作。

1 个答案:

答案 0 :(得分:0)

您可以在子查询中使用窗口函数ROW_NUMBER()为具有相同job_name的记录组中的每个日志条目分配一个等级。

如果仅希望最后3个运行失败的作业的名称,则可以在外部查询中使用聚合。 HAVING子句在相关记录中进行过滤。

SELECT job_name
FROM (
    SELECT 
        job_name, 
        status,
        ROW_NUMBER() OVER(PARTITION BY job_name ORDER BY log_date DESC) rn 
    FROM sys.all_scheduler_job_run_details
) x
WHERE rn <= 3
GROUP BY job_name
HAVING
    MIN(status) = 'FAILED'
    AND MAX(status) = 'FAILED'

NB:

  • 我认为您无需引入系统视图ALL_SCHEDULER_JOBS即可获得预期结果(ALL_SCHEDULER_JOB_RUN_DETAILS拥有我们所需的所有信息)
  • 我怀疑您想使用log_date而不是log_id来对记录进行排序

另一方面,如果您需要满足条件的作业的整个日志条目,那么您将需要一个附加级别的子查询,例如:

SELECT * FROM (
    SELECT 
        x.*, 
        MAX(status) OVER(PARTITION BY job_name) max_status,
        MIN(status) OVER(PARTITION BY job_name) min_status
    FROM (
        SELECT 
            j.*, 
            ROW_NUMBER() OVER(PARTITION BY job_name ORDER BY log_date DESC) rn 
        FROM sys.all_scheduler_job_run_details j
    ) x
    WHERE rn <= 3
) y 
WHERE 
    max_status = 'FAILED'
    AND min_status = 'FAILED'