I have a requirement to schedule the procedure using Oracle DBA Scheduler to run on the 4th working day every month (excluding bank holidays and weekends). After doing some research it seems that Oracle DBA Scheduler does not recognize working days or bank holidays.
I have come up with below two ideas:
schedule another procedure to run on the 1st of every month and check when is the 4th working day and adjust the repeat_interval in the first scheduled job so it runs on 4th working day.
schedule the job to run monthly but only for the first 7 days, and in the run procedure create a check if today is 4th working day and if yes then execute if not do not run.
I do not have much experience with scheduling jobs, so I am not sure if option 1 is recommended, but it seems easier. I guess option 2 is still ok, but it will be more time-consuming to complete.
What option would you use? Or maybe something completely different?
Thanks
CodePudding user response:
You can have an SQL resulting with 4th working day in every month of the year. You should get holiday dates for the actual year.
Example:
Czech Republic Public Holidays 2022
Date | Day | Holiday |
---|---|---|
01.01.2022 | Sat | New Year's Day |
15.04.2022 | Fri | Good Friday |
18.04.2022 | Mon | Easter Monday |
01.05.2022 | Sun | May Day |
08.05.2022 | Sun | Liberation Day |
05.07.2022 | Tue | St Cyril and St Methodius Day |
06.07.2022 | Wed | Jan Hus Day |
28.09.2022 | Wed | Statehood Day |
28.10.2022 | Fri | Independence Day |
17.11.2022 | Thu | Freedom and Democracy Day |
24.12.2022 | Sat | Christmas Eve |
25.12.2022 | Sun | Christmas Day |
26.12.2022 | Mon | 2nd Day of Christmas |
Create a CTE holidays and another CTE named days holding 365 days with some attributes like day of week, is it a working day or not and distinct counters for working and non working days within a month:
WITH
holidays AS
(
Select To_Date('01.01.2022', 'dd.mm.yyyy') "A_DATE", 'New Year''s Day' "A_NAME" From Dual Union All
Select To_Date('15.04.2022', 'dd.mm.yyyy') "A_DATE", 'Good Friday ' "A_NAME" From Dual Union All
Select To_Date('18.04.2022', 'dd.mm.yyyy') "A_DATE", 'Easter Monday' "A_NAME" From Dual Union All
Select To_Date('01.05.2022', 'dd.mm.yyyy') "A_DATE", 'May Day ' "A_NAME" From Dual Union All
Select To_Date('08.05.2022', 'dd.mm.yyyy') "A_DATE", 'Liberation Day' "A_NAME" From Dual Union All
Select To_Date('05.07.2022', 'dd.mm.yyyy') "A_DATE", 'St Cyril and St Methodius Day' "A_NAME" From Dual Union All
Select To_Date('06.07.2022', 'dd.mm.yyyy') "A_DATE", 'Jan Hus Day' "A_NAME" From Dual Union All
Select To_Date('28.09.2022', 'dd.mm.yyyy') "A_DATE", 'Statehood Day' "A_NAME" From Dual Union All
Select To_Date('28.10.2022', 'dd.mm.yyyy') "A_DATE", 'Independence Day' "A_NAME" From Dual Union All
Select To_Date('17.11.2022', 'dd.mm.yyyy') "A_DATE", 'Freedom and Democracy Day' "A_NAME" From Dual Union All
Select To_Date('24.12.2022', 'dd.mm.yyyy') "A_DATE", 'Christmas Eve ' "A_NAME" From Dual Union All
Select To_Date('25.12.2022', 'dd.mm.yyyy') "A_DATE", 'Christmas Day' "A_NAME" From Dual Union All
Select To_Date('26.12.2022', 'dd.mm.yyyy') "A_DATE", '2nd Day of Christmas ' "A_NAME" From Dual
),
days AS
( Select
To_Date('01.01.' || To_Char(SYSDATE, 'yyyy'), 'dd.mm.yyyy') (LEVEL - 1) "DATE_ID",
To_Char(To_Date('01.01.' || To_Char(SYSDATE, 'yyyy'), 'dd.mm.yyyy') (LEVEL - 1), 'DY') "DAY_OF_WEEK",
CASE
WHEN To_Char(To_Date('01.01.' || To_Char(SYSDATE, 'yyyy'), 'dd.mm.yyyy') (LEVEL - 1), 'DY') NOT IN('SAT', 'SUN') And
To_Date('01.01.' || To_Char(SYSDATE, 'yyyy'), 'dd.mm.yyyy') (LEVEL - 1) Not IN(Select A_DATE From holidays)
THEN 'YES'
ELSE '-'
END "WRKDAY",
Count(*) OVER(Partition By To_Char(To_Date('01.01.' || To_Char(SYSDATE, 'yyyy'), 'dd.mm.yyyy') (LEVEL - 1), 'yyyymm') ||
CASE
WHEN To_Char(To_Date('01.01.' || To_Char(SYSDATE, 'yyyy'), 'dd.mm.yyyy') (LEVEL - 1), 'DY') NOT IN('SAT', 'SUN') And
To_Date('01.01.' || To_Char(SYSDATE, 'yyyy'), 'dd.mm.yyyy') (LEVEL - 1) Not IN(Select A_DATE From holidays)
THEN 'YES'
ELSE '-'
END
Order By To_Date('01.01.' || To_Char(SYSDATE, 'yyyy'), 'dd.mm.yyyy') (LEVEL - 1)) "DAY_NUM"
From
Dual
Connect By
LEVEL <= 365
Order By
LEVEL
)
Now you can get all the dates of interest for year 2022:
Select
DATE_ID, DAY_OF_WEEK, WRKDAY, DAY_NUM
From
days
Where
WRKDAY = 'YES' And DAY_NUM = 4
Order By
DATE_ID
The result is:
DATE_ID | DAY_OF_WEEK | WRKDAY | DAY_NUM |
---|---|---|---|
06-JAN-22 | THU | YES | 4 |
04-FEB-22 | FRI | YES | 4 |
04-MAR-22 | FRI | YES | 4 |
06-APR-22 | WED | YES | 4 |
05-MAY-22 | THU | YES | 4 |
06-JUN-22 | MON | YES | 4 |
08-JUL-22 | FRI | YES | 4 |
04-AUG-22 | THU | YES | 4 |
06-SEP-22 | TUE | YES | 4 |
06-OCT-22 | THU | YES | 4 |
04-NOV-22 | FRI | YES | 4 |
06-DEC-22 | TUE | YES | 4 |
This dataset now can be used for any scheduling policy that you want. You just have to check if your actual date is listed within or you can use these dates to instruct the scheduler.
Regards...