我在 Linux 主机上安排了一些 cron 作业。每个作业都会将执行日志写入 Oracle 数据库表中。该表有一个结果列,可以用“OK”或“KO”来评估。该表还有一个时间戳列,该列的值是作业的上次执行时间。这样我对工作结果就很确定了。现在我需要确保该作业确实已运行。我有另一个包含作业 ID 和 cron 表达式的表,例如:
JOB_ID SCHEDULE
102 00 09 * * *
Run Code Online (Sandbox Code Playgroud)
如何编写 sql select 来根据 SCHEDULE 字段(cron 表达式)检查上次执行时间?
我将不胜感激任何建议,我可以改变我的方法,但我想在数据库表中使用 cron 语法
问候乔瓦
您可以使用该regexp_substr函数从计划元组中提取单个元素。例如regexp_substr(schedule, '[0-9*]+', 1,1)将提取分钟元素,而regexp_substr(sched, '[0-9*]+', 1, 2)将提取小时元素。第四个参数选择所需的元素。然后,您可以使用EXTRACT或TO_CHAR函数来获取时间戳的各个部分以进行比较。
with cron(ID, Sched) as (
select 102, '00 9 * * * *' from dual
), exec(id, ts) as (
select 102, to_timestamp('2017-11-05 9:00:00', 'yyyy-mm-dd hh24:mi:ss') from dual union all
select 102, to_timestamp('2017-11-05 9:05:00', 'yyyy-mm-dd hh24:mi:ss') from dual
), c2 as (
select id
, sched
, regexp_substr(sched,'[0-9*]+',1,1) min
, regexp_substr(sched,'[0-9*]+',1,2) hour
, regexp_substr(sched,'[0-9*]+',1,3) day
, regexp_substr(sched,'[0-9*]+',1,4) mon
, regexp_substr(sched,'[0-9*]+',1,5) wday
, regexp_substr(sched,'[0-9*]+',1,6) year
from cron
)
select c2.*
, exec.ts
, case when (year = '*' or to_number(to_char(ts,'yyyy')) = to_number(year))
and (mon = '*' or to_number(to_char(ts,'mm') ) = to_number(mon ))
and (day = '*' or to_number(to_char(ts,'dd') ) = to_number(day ))
and (hour = '*' or to_number(to_char(ts,'hh24')) = to_number(hour))
and (min = '*' or to_number(to_char(ts,'mi') ) = to_number(min ))
and (wday = '*' or to_number(to_char(ts,'d') ) = to_number(wday))
then 'OK'
else 'KO'
end Match
from exec
join c2
on c2.id = exec.id;
Run Code Online (Sandbox Code Playgroud)
根据需要从 case 语句中部分或全部移动逻辑表达式以获得所需的结果。
| 归档时间: |
|
| 查看次数: |
13643 次 |
| 最近记录: |