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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
| create or replace PROCEDURE Abo_Churn_Regroupe_Email
IS
v_debut date;
v_fin date;
--Déclaration d'un nouveau type
type type_tab_email is table of ABO_CHURN_LOGIN_CAS.EMAIL%type;
type type_tab_debut is table of ABO_CHURN_LOGIN_CAS.DEBUT%type;
type type_tab_fin is table of ABO_CHURN_LOGIN_CAS.FIN%type;
type type_tab_portail is table of ABO_CHURN_LOGIN_CAS.PORTAIL%type;
--Déclaration variable du nouveau type
tab_email type_tab_email;
tab_debut type_tab_debut;
tab_fin type_tab_fin;
tab_portail type_tab_portail;
--Déclaration des curseurs
cursor c_logins_abonnes is
select unique email
from ABO_CHURN_LOGIN_CAS
order by email;
cursor c_ses_emails (un_email VARCHAR2) is
select a.debut, a.fin, a.portail
from ABO_CHURN_LOGIN_CAS a
where a.email = un_email
order by a.email, a.debut;
jour CONSTANT INTEGER := 1;
delai_regroupement CONSTANT INTEGER := 30 * jour;
nb_insert integer;
BEGIN
v_debut := sysdate;
nb_insert := 0;
-- on vide la table
DELETE ABO_CHURN_EMAIL_CAS;
--Utilisation du premier curseur
open c_logins_abonnes;
fetch c_logins_abonnes bulk collect into tab_email;
close c_logins_abonnes;
if tab_email.first is not null then
FOR login_abonne IN tab_email.first..tab_email.last LOOP
DECLARE
nb_lignes_regroupées INTEGER;
premiere_ligne BOOLEAN := TRUE;
debut_regroupement_courant DATE := NULL;
fin_regroupement_courant DATE := NULL;
portail_courant ABO_CHURN_LOGIN_CAS.PORTAIL%TYPE:=NULL;
BEGIN
--Utilisation du deuxième curseur
open c_ses_emails(tab_email(login_abonne));
fetch c_ses_emails bulk collect into tab_debut, tab_fin, tab_portail;
close c_ses_emails;
nb_lignes_regroupées := 0;
if tab_debut.first is not null then
if tab_debut.count <> 0 then
FOR un_email IN tab_debut.first..tab_debut.last LOOP
-- DBMS_OUTPUT.PUT_LINE ('D : '||un_email.debut||' F : '||un_email.fin||' debut_regroupement_courant : '|| debut_regroupement_courant|| ' fin_regroupement_courant : '|| fin_regroupement_courant|| ' nb_regroupement : '|| nb_lignes_regroupées|| ' DEBUT');
IF premiere_ligne THEN
-- On teste si le curseur parcourt la 1e ligne d'un groupe
premiere_ligne := FALSE;
-- On initialise les variables de début et de fin du regroupement courant
debut_regroupement_courant := tab_debut(un_email);
fin_regroupement_courant := tab_fin(un_email);
nb_lignes_regroupées := 1;
-- DBMS_OUTPUT.PUT_LINE ('D : '||un_email.debut||' F : '||un_email.fin||' debut_regroupement_courant : '|| debut_regroupement_courant|| ' fin_regroupement_courant : '|| fin_regroupement_courant|| ' nb_regroupement : '|| nb_lignes_regroupées|| ' 1e ligne groupe');
ELSE
-- Ce n'est pas une première ligne
IF tab_debut(un_email) - fin_regroupement_courant < delai_regroupement THEN
-- Pas de rupture => On regroupe
-- On prend le min de la date de début du regroupement courant et de la date de début lue (cas où les abonnements sont englobés)
debut_regroupement_courant := LEAST(debut_regroupement_courant, tab_debut(un_email));
-- On prend le max de la date de fin du regroupement courant et de la date de fin lue (cas où les abonnements sont englobés)
fin_regroupement_courant := GREATEST(fin_regroupement_courant, tab_fin(un_email));
-- Ne pas oublier de compter le regroupement
nb_lignes_regroupées := nb_lignes_regroupées + 1;
ELSE
-- Rupture, on enregistre le groupe courant.
-- DBMS_OUTPUT.PUT_LINE ('D : '||un_email.debut||' F : '||un_email.fin||' debut_regroupement_courant : '|| debut_regroupement_courant|| ' fin_regroupement_courant : '|| fin_regroupement_courant|| ' nb_regroupement : '|| nb_lignes_regroupées|| ' AVANT INSERT MILIEU');
INSERT INTO ABO_CHURN_EMAIL_CAS VALUES (tab_email(login_abonne), debut_regroupement_courant, fin_regroupement_courant, tab_portail(un_email), nb_lignes_regroupées, 'MILIEU');
nb_insert := nb_insert + 1;
-- Et on ouvre le groupe suivant à partir de la ligne de rupture
debut_regroupement_courant := tab_debut(un_email);
fin_regroupement_courant := tab_fin(un_email);
nb_lignes_regroupées := 1;
-- DBMS_OUTPUT.PUT_LINE ('D : '||un_email.debut||' F : '||un_email.fin||' debut_regroupement_courant : '|| debut_regroupement_courant|| ' fin_regroupement_courant : '|| fin_regroupement_courant|| ' nb_regroupement : '|| nb_lignes_regroupées|| ' APRES INSERT MILIEU');
END IF;
END IF;
-- Passage des variables locales à la sortie de la boucle
portail_courant:= tab_portail(un_email);
END LOOP;
end if;
end if;
-- DBMS_OUTPUT.PUT_LINE (' debut_regroupement_courant : '|| debut_regroupement_courant|| ' fin_regroupement_courant : '|| fin_regroupement_courant|| ' nb_regroupement : '|| nb_lignes_regroupées|| ' DERNIER');
INSERT INTO ABO_CHURN_EMAIL_CAS VALUES (tab_email(login_abonne), debut_regroupement_courant, fin_regroupement_courant, portail_courant, nb_lignes_regroupées, 'DERNIER');
nb_insert := nb_insert + 1;
END;
END LOOP;
end if;
v_fin := sysdate;
insert into log_churns (debut, fin, duree, description)
values (v_debut, v_fin, cast(v_fin as timestamp) - cast(v_debut as timestamp), 'regroupe email avec '|| nb_insert||' lignes insérées');
COMMIT;
END Abo_Churn_Regroupe_Email; |