CREATE OR REPLACE function f_sum_day_job_holiday(inizio_data in date, fine_data in date, flag varchar2 ) return number is countBusiness number := 0; /* Contatore gg feriali */ countFestivi number := 0; /* Contatore gg festivi */ countFestiviSanti number := 0; /* Contatore gg feste & santi */ countApp number := 0; /* Contatore di appoggio */ item number := 0; /* Contatore di appoggio */ pasqua_app varchar2(50); /* Data Pasqua stringa */ data_pasqua date; /* Data Pasqua */ anno_attuale varchar2(50); count_gg_tot number := 0; /* Contatore gg totali da inizio a fine data */ begin /*Funziona che ritorna o il numero dei giorni lavorati o il numero di giorni festivi dato un intervallo di tempo Es.: select f_sum_day_job_holiday ( '7-Gen-2012', '14-Gen-2012','F') from dual; select f_sum_day_job_holiday ( '1-Gen-2012', '7-Gen-2012',null) from dual; */ /* Verifico che la data inizio sia minore della data di fine. In questo caso restituisco -9 */ if ( inizio_data > fine_data ) then return (-9); end if; /* loop per calcolare giorni feriali */ while ( inizio_data+item <= fine_data ) loop if ( (To_char(To_date(inizio_data+item, 'dd-mon-yy'), 'DY','nls_date_language = italian')) != 'SAB' ) and (To_char(To_date(inizio_data, 'dd-mon-yy')+item, 'DY', 'nls_date_language = italian') != 'DOM' ) then countBusiness:=countBusiness+1; end if; item:=item+1; end loop; count_gg_tot := item; ---- togliere i gg santi dal conteggio --- e la Pasqua anno_attuale := To_char(To_date(inizio_data, 'dd-mon-yyyy'), 'YY', 'nls_date_language = italian'); anno_attuale:= anno_attuale + 2000; /* query per determinare giorno di Pasqua tra '1900' e '2099' */ Select DECODE(SIGN(32 - (22 +MOD(((19 * MOD( anno_attuale ,19)) + 24),30) +MOD(((2 * MOD( anno_attuale ,4)) +(4 * MOD( anno_attuale ,7)) +(6 * MOD(((19 * MOD( anno_attuale ,19)) + 24),30)) +5),7))),-1,(MOD(((19 * MOD( anno_attuale ,19)) + 24),30) +MOD(((2 * MOD( anno_attuale ,4)) +(4 * MOD( anno_attuale ,7)) +(6 * MOD(((19 * MOD( anno_attuale ,19)) + 24),30)) +5),7) -9)||'-04-'|| anno_attuale ,(22 +MOD(((19 * MOD( anno_attuale ,19)) + 24),30) +MOD(((2 * MOD( anno_attuale ,4)) +(4 * MOD( anno_attuale ,7)) +(6 * MOD(((19 * MOD( anno_attuale ,19)) + 24),30)) +5),7))||'-03-'|| anno_attuale ) into pasqua_app from Dual where anno_attuale between '1900' and '2099'; data_pasqua:=to_date(pasqua_app,'dd-mm-yy'); -- Verifico ogni singolo giorno se il santo cade di domenica o di sabato. item:=0; /* Loop per determinare i giorni festivi Santi e se cadenti di Sabato e Domenica Tracciato tabella gg_festivi: GIORNO (DATE) DESCRIZIONE (VARCHAR2 50) ES.: 01/01/1900 Capodanno 06/01/1900 Epifania .... ... */ while ( inizio_data+item <= fine_data ) loop select count(*) into countApp from gg_festivi a where to_char(inizio_data+item,'DD-MM') = to_char(GIORNO,'DD-MM'); countFestivi:=countApp+countFestivi; -- Verifico se il giorno è pasquetta if ( (inizio_data+item) = (data_pasqua+1 ) ) then countFestivi:=1+countFestivi; end if; if ( ( countApp > 0 AND To_char(To_date(inizio_data, 'dd-mon-yy')+item, 'DY','nls_date_language = italian') = 'SAB' ) OR (countApp > 0 AND (To_char(To_date(inizio_data, 'dd-mon-yy')+item, 'DY', 'nls_date_language = italian')) = 'DOM' ) ) then countFestiviSanti:=countFestiviSanti+1; end if; item:=item+1; end loop; /* Se il flag è settato F restituisco i gorni festivi altrimenti i giorni lavorati */ if ( upper(flag) = 'F' ) then return ((count_gg_tot-countBusiness)+(countFestivi-countFestiviSanti)); else return (countBusiness-countFestivi+countFestiviSanti); end if; END f_sum_day_job_holiday; /