passed this ticket and thought I put my solution.
My requirements where a bit more then just excluding the weekenddays.
I exclude here weekends (which are country specific
)
exclude public holidays (stored in a table) if they are in a specific region
and then something else (called weeklyclosingdays)
i created an oracle function, providing all parameters that are not static and it returns the sum of weekends, public holidays,…
Then I substract this in a view from the date1-Date2 so I get a kind of corrected delay, or nr of workingdays if you please.
hope it helps,
I tried a lot of other things before this, but this is really performant and allows me to take into account a lot more then just the weekends.
ciao, Meutte
CREATE OR REPLACE FUNCTION FCT_CalcForeseenDelay (
T_FirstDate DATE,
T_LastDate DATE,
T_countrycode INTEGER,
T_weeklyclosingdays varchar2,
T_Region number,
T_CheckWeekend number --0= don't check for a 'weekend'day, 1 check for weekenddays
)
RETURN INTEGER
IS
V_Firstdate DATE;
V_Foreseen NUMBER := 0;
V_dayofweek varchar2(2);
E_NotFilled EXCEPTION;
CURSOR c_holiday
IS
SELECT holiday_date, region
FROM dwh.d_holidays
WHERE countryansicode = T_countrycode;
BEGIN
V_Firstdate := TRUNC (T_Firstdate+1);
If T_LastDate is null or T_FirstDate is null then RAISE E_notfilled ; end if;
WHILE V_Firstdate <= T_LastDate
LOOP
select DECODE (TO_CHAR (V_Firstdate, 'dy'),
'mon', SUBSTR (T_weeklyclosingdays, 1, 1),
'tue', SUBSTR (T_weeklyclosingdays, 2, 1),
'wed', SUBSTR (T_weeklyclosingdays, 3, 1),
'thu', SUBSTR (T_weeklyclosingdays, 4, 1),
'fri', SUBSTR (T_weeklyclosingdays, 5, 1),
'sat', SUBSTR (T_weeklyclosingdays, 6, 1),
'sun', SUBSTR (T_weeklyclosingdays, 7, 1),
999
)into v_dayofweek from dual ;
if (T_CheckWeekend = 1 and T_countrycode not in (31,34) and TO_CHAR (V_Firstdate, 'dy') IN ('sun', 'mon') )
or (T_CheckWeekend = 1 and T_countrycode in (34) and TO_CHAR (V_Firstdate, 'dy') IN ('sun', 'sat')and V_Firstdate<>trunc(T_LastDate))
or (T_CheckWeekend = 1 and T_countrycode in (31) and TO_CHAR (V_Firstdate, 'dy') IN ('sun', 'sat'))
then V_Foreseen := V_Foreseen + 1; -- increment holiday counter
else
if v_dayofweek = 'C'
THEN V_Foreseen := V_Foreseen + 1;
else
FOR recholiday IN c_holiday
LOOP
IF V_Firstdate = recholiday.holiday_date and
(case when T_countrycode= 34 and T_region = 999 then recholiday.region else T_region end) =case when T_region<>999 and recholiday.region=999 then T_Region else recholiday.region end
THEN
V_Foreseen := V_Foreseen + 1; -- increment holiday counter
END IF;
END LOOP;
end if;
end if;
V_Firstdate := V_Firstdate + 1;
END LOOP;
RETURN V_Foreseen;
EXCEPTION
when E_NotFilled then Return 999;
END ;
/
meutte
(BOB member since 2007-12-06)