I have some cron jobs scheduled on a Linux host. Each job writes execution log in an Oracle database table. The table has a result column that can be valued with 'OK' or 'KO'. The table also has a timestamp column that is valued with the last execution time for the job. In this way I'm sure about the job result. Now I need to be sure that the job has actually ran. I have another table with job ID and cron expression, for example:
JOB_ID SCHEDULE
102 00 09 * * *
How can I write a sql select to check the last execution time against the SCHEDULE field (cron expression)?
I will appreciate any suggestion, I can change the my approach but I would like to use the cron syntax inside the database table
Regards Giova
You can use the regexp_substr function to extract individual elements from the schedule tuple. For example regexp_substr(schedule, '[0-9*]+', 1,1) will extract the minute element, while regexp_substr(sched, '[0-9*]+', 1, 2) will extract the hour element. The 4th parameter selects the desired element. You can then use either the EXTRACT or TO_CHAR function to get at various portions of your timestamp for comparison.
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;
move the logical expression from the case statement in part or whole as needed to get the results you need.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With