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; | 
Partager