1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| create table JOURS_FERIES
( XDATE DATE );
insert into JOURS_FERIES ( XDATE ) values (to_date ('01/01/2000','DD/MM/RRRR'));
insert into JOURS_FERIES ( XDATE ) values (to_date ('01/05/2000','DD/MM/RRRR'));
insert into JOURS_FERIES ( XDATE ) values (to_date ('08/05/2000','DD/MM/RRRR'));
insert into JOURS_FERIES ( XDATE ) values (to_date ('14/07/2000','DD/MM/RRRR'));
insert into JOURS_FERIES ( XDATE ) values (to_date ('15/08/2000','DD/MM/RRRR'));
insert into JOURS_FERIES ( XDATE ) values (to_date ('01/11/2000','DD/MM/RRRR'));
insert into JOURS_FERIES ( XDATE ) values (to_date ('11/11/2000','DD/MM/RRRR'));
insert into JOURS_FERIES ( XDATE ) values (to_date ('25/12/2000','DD/MM/RRRR'));
commit;
create or replace function NB_JOURS_OUVRES ( dateDeb date) return number is
/* Author TASKA */
dateFin date ;
nbJours number(2);
nbJoursOuvres number(2);
nbJoursFeries number(2) := 0;
TYPE jour_feries IS TABLE OF date INDEX BY BINARY_INTEGER;
jf jour_feries;
-- cptJF number(2); -- nombre de jours féries
cpt number(2) := 1;
begin
dbms_output.put_line ('Mois de : '||TO_CHAR(dateDeb,'MONTH RRRR'));
/* ICI l'idée est de charger la table des jours fériés en mémoire
pour éviter les accés bases
Il est à noter pour la suite que nous ferons abstraction à l'année renseignée (pour nuke_y!)
*/
for rec in (Select XDATE from JOURS_FERIES) loop
jf(cpt):= rec.XDATE;
cpt := cpt+1 ;
end loop;
-- Calcul du nombre de jours du mois
select LAST_DAY( dateDeb)-to_date (dateDeb)+1 into nbJours from dual ;
--dbms_output.put_line (nbJours);
nbJoursOuvres := nbJours;
nbJours := nbJours -1;
while nbJours >=0 loop
-- dbms_output.put_line ('Jours >'||TO_CHAR(dateDeb+nbJours,'DAY DD/MM/RRRR') ||' > nbJoursOuvres OLD '||nbJoursOuvres);
-- Recherche dans le tableau mémoire si le jour courrant existe sous la forme DD/MM
for i in 1..jf.LAST loop
if TO_CHAR(dateDeb+nbJours,'DD/MM') = to_char (jf(i),'DD/MM') then
-- Le jour existe, alors nous aurons 1 jour ouvré de moins
nbJoursOuvres := nbJoursOuvres -1 ;
-- dbms_output.put_line ('Jours férié '||TO_CHAR(dateDeb+nbJours,'DAY DD/MM/RRRR')||' > nbJoursOuvres FE '||nbJoursOuvres);
goto suite; -- allons vérifier le jour suivant
end if;
end loop;
-- Si le jour courrant n'est pas un jour férié alors vérifions qu'il ne s'agit
-- ni d'un SAMEDI ni d'un DIMANCHE !
-- Ne aps omettre le RTRIM sinon .... ( essayer ! )
if rtrim(TO_CHAR(dateDeb+nbJours, 'DAY')) in ('SAMEDI','DIMANCHE') then
nbJoursOuvres := nbJoursOuvres -1 ;
-- encore un jour ouvré en moins
-- dbms_output.put_line ('Jours chomé '||TO_CHAR(dateDeb+nbJours,'DAY DD/MM/RRRR')||' > nbJoursOuvres WE '||nbJoursOuvres);
end if;
<<suite>>
nbJours := nbJours -1; -- jour courant = 1er du mois + index
end loop;
-- dbms_output.put_line ( 'Total Jours ouvrés : '|| nbJoursOuvres );
return nbJoursOuvres ;
end; |