IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PL/SQL Oracle Discussion :

Pb requete, reprise PL SQL


Sujet :

PL/SQL Oracle

  1. #1
    Membre régulier Avatar de Cvanhove
    Homme Profil pro
    Concepteur Développeur Informatique
    Inscrit en
    Septembre 2014
    Messages
    174
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Deux Sèvres (Poitou Charente)

    Informations professionnelles :
    Activité : Concepteur Développeur Informatique

    Informations forums :
    Inscription : Septembre 2014
    Messages : 174
    Points : 70
    Points
    70
    Par défaut Pb requete, reprise PL SQL
    Bonjour,

    J'ai un soucis avec ma requête PL SQL (ça fait plusieurs années que j'en avais pas fait et la reprise est difficile!)
    J'ai 4 erreurs remontées visiblement dut à un pb de structure (Un Begin mal déclaré peut etre?)

    Voici mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    create or replace procedure  DWAUTO_PURGE_ALL_TABLES(NB_MOIS_RETENTION number)
    is
    maTable varchar2(30 char);
    TABLE_NAME varchar2(100 char);
    nbEnr integer;
    currTable varchar2(30 char);
    tbl_exist varchar2(30 char);
     
    BEGIN
            select TABLE_NAME into currTable from DBDWAUTOUSR.TMP_PURGE_ALL_TABLES;
            EXCEPTION WHEN no_data_found THEN
                currTable := ' ';
    	--END;
     
    	if currTable is null then
    		---init avec une chaine vide pour traiter toutes les tables
    		insert into DBDWAUTOUSR.TMP_PURGE_ALL_TABLES values (currTable);
    	end if;
     
    	for maTable in (select distinct substr(TABLE_NAME,1,16) as TABLE_NAME from all_tables where (REGEXP_like(TABLE_NAME,'^M[0-9]{6}_S[0-9]{7}$') or TABLE_NAME='MSG') AND OWNER = 'DBDWAUTOUSR' AND TABLE_NAME > currTable order by 1) loop
     
    		select count(*) into tbl_exist from all_tables where TABLE_NAME = 'TAB_TMP' and OWNER = 'DBDWAUTOUSR';
    		if tbl_exist = 1 then -- Si la table TMP existe alors...
    			select count(*) into cnt from maTable.TABLE_NAME;
    			if cnt != 0 then -- Si la table source n'est pas vide, on Drop la table TMP
    				execute immediate 'drop table DBDWAUTOUSR.TAB_TMP';
    			end if; -- Sinon on skip le Drop de la table TMP et on passe à la suite
    		end if;
     
    		dbms_output.put_line( 'create table DBDWAUTOUSR.TAB_TMP as select * from DBDWAUTOUSR.' || maTable.TABLE_NAME || ' WHERE date_rec >= add_months(sysdate, - ' || NB_MOIS_RETENTION || ')-1');
    		execute immediate 'create table DBDWAUTOUSR.TAB_TMP as select * from DBDWAUTOUSR.' || maTable.TABLE_NAME || ' WHERE date_rec >= add_months(sysdate, - ' || NB_MOIS_RETENTION || ')-1';
    		execute immediate 'truncate table DBDWAUTOUSR.' || maTable.TABLE_NAME ;
    		execute immediate 'insert /*+append */ into DBDWAUTOUSR. ' || maTable.TABLE_NAME || ' select * from DBDWAUTOUSR.TAB_TMP' ;
    		execute immediate 'drop table DBDWAUTOUSR.TAB_TMP purge' ;
    		update DBDWAUTOUSR.TMP_PURGE_ALL_TABLES set TABLE_NAME = maTable.TABLE_NAME;
    	end loop;
     
    	select count(*) into tbl_exist from all_tables where TABLE_NAME = 'TAB_TMP' and OWNER = 'DBDWAUTOUSR';
    	if tbl_exist = 1 then -- Si la table TMP existe alors...
    		delete from DBDWAUTOUSR.TMP_PURGE_ALL_TABLES;
    	end if;
     
    END DWAUTO_PURGE_ALL_TABLES;
    Et voici mes erreurs :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Erreur(24,4): PL/SQL: SQL Statement ignored
    Erreur(24,42): PL/SQL: ORA-00942: Table ou vue inexistante
    Erreur(25,4): PL/SQL: Statement ignored
    Erreur(25,7): PLS-00201: identifier 'CNT' must be declared
    J'ai d'abord pensé à une ligne non fermé par un ";" mais visiblement c'est pas ça...
    Si quelqu'un à des pistes ou voit une erreur je suis preneur !

    Merci d'avance pour votre aide.
    Cordialement, le volatile!
    "Crôa, Crôa"

  2. #2
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Erreur(25,7): PLS-00201: identifier 'CNT' must be declared

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT COUNT(*) INTO cnt
    La variable cnt n'est pas déclaré


    Ensuite, c'est bizarre ce code, mais c'est peut être voulu

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    BEGIN
            SELECT TABLE_NAME INTO currTable FROM DBDWAUTOUSR.TMP_PURGE_ALL_TABLES;
    EXCEPTION WHEN no_data_found THEN
                currTable := ' ';
    	--END;
     
    	IF currTable IS NULL THEN
    		---init avec une chaine vide pour traiter toutes les tables
    		INSERT INTO DBDWAUTOUSR.TMP_PURGE_ALL_TABLES VALUES (currTable);
    	END IF;
    Ca veut dire que tout le traitement ne se fait que pour l'exception NO_DATA_FOUND, et le currTable ne sera donc jamais NULL, mais vaudra toujours ' '
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  3. #3
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 783
    Points
    30 783
    Par défaut
    L'erreur identifiée à la ligne 25 est claire :
    • La variable cnt n'a pas été déclarée au début du bloc de code.

    Celle de la ligne précédent l'est tout autant :
    • La table maTable.TABLE_NAME n'existe pas.
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  4. #4
    Membre régulier Avatar de Cvanhove
    Homme Profil pro
    Concepteur Développeur Informatique
    Inscrit en
    Septembre 2014
    Messages
    174
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Deux Sèvres (Poitou Charente)

    Informations professionnelles :
    Activité : Concepteur Développeur Informatique

    Informations forums :
    Inscription : Septembre 2014
    Messages : 174
    Points : 70
    Points
    70
    Par défaut
    Effectivement pour le cnt, je l'avais oublié, par contre le maTable.TABLE_NAME est bien déclaré au début. Est-ce un warning qui n'a pas lieu d'être?
    Cordialement, le volatile!
    "Crôa, Crôa"

  5. #5
    Membre expérimenté Avatar de Cincinnatus
    Homme Profil pro
    Développeur d'applications métier
    Inscrit en
    Mars 2007
    Messages
    592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur d'applications métier
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2007
    Messages : 592
    Points : 1 679
    Points
    1 679
    Par défaut
    Citation Envoyé par Cvanhove Voir le message
    Effectivement pour le cnt, je l'avais oublié, par contre le maTable.TABLE_NAME est bien déclaré au début. Est-ce un warning qui n'a pas lieu d'être?
    maTable et TABLE_NAME sont des variables déclarées au début, en effet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    maTable varchar2(30 char); TABLE_NAME varchar2(100char);
    
    Mais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select count(*)into cnt from maTable.TABLE_NAME;
    ne peut pas marcher comme ça. En execute immediate, ça pourrait mieux marcher, comme tu le fais pour d'autres instructions.

  6. #6
    Membre régulier Avatar de Cvanhove
    Homme Profil pro
    Concepteur Développeur Informatique
    Inscrit en
    Septembre 2014
    Messages
    174
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Deux Sèvres (Poitou Charente)

    Informations professionnelles :
    Activité : Concepteur Développeur Informatique

    Informations forums :
    Inscription : Septembre 2014
    Messages : 174
    Points : 70
    Points
    70
    Par défaut
    D'accord mais j'ai un doute, passer cette ligne en execute immediate me permet quand même d'alimenter ma variable cnt?
    Cordialement, le volatile!
    "Crôa, Crôa"

  7. #7
    Membre régulier Avatar de Cvanhove
    Homme Profil pro
    Concepteur Développeur Informatique
    Inscrit en
    Septembre 2014
    Messages
    174
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Deux Sèvres (Poitou Charente)

    Informations professionnelles :
    Activité : Concepteur Développeur Informatique

    Informations forums :
    Inscription : Septembre 2014
    Messages : 174
    Points : 70
    Points
    70
    Par défaut
    Bon j'ai passé ma ligne en execute immediate comme conseiller et j'arrive à compiler, ce qui me donne ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    create or replace procedure  DWAUTO_PURGE_ALL_TABLES(NB_MOIS_RETENTION number)
    is
    maTable varchar2(30 char);
    TABLE_NAME varchar2(100 char);
    nbEnr integer;
    currTable varchar2(30 char);
    tbl_exist varchar2(30 char);
    cnt integer;
     
    BEGIN
            select TABLE_NAME into currTable from DBDWAUTOUSR.TMP_PURGE_ALL_TABLES;
            EXCEPTION WHEN no_data_found THEN
                currTable := ' ';
     
    	if currTable is null then
    		---init avec une chaine vide pour traiter toutes les tables
    		insert into DBDWAUTOUSR.TMP_PURGE_ALL_TABLES values (currTable);
    	end if;
     
    	for maTable in (select distinct substr(TABLE_NAME,1,16) as TABLE_NAME from all_tables where (REGEXP_like(TABLE_NAME,'^M[0-9]{6}_S[0-9]{7}$') or TABLE_NAME='MSG') AND OWNER = 'DBDWAUTOUSR' AND TABLE_NAME > currTable order by 1) loop
     
    		select count(*) into tbl_exist from all_tables where TABLE_NAME = 'TAB_TMP' and OWNER = 'DBDWAUTOUSR';
    		if tbl_exist = 1 then -- Si la table TMP existe alors...
    			execute immediate 'select count(*) into cnt from DBDWAUTOUSR.' || maTable.TABLE_NAME;
    			if cnt != 0 then -- Si la table source n'est pas vide, on Drop la table TMP
    				execute immediate 'drop table DBDWAUTOUSR.TAB_TMP';
    			end if; -- Sinon on skip le Drop de la table TMP et on passe à la suite
    		end if;
     
    		dbms_output.put_line( 'create table DBDWAUTOUSR.TAB_TMP as select * from DBDWAUTOUSR.' || maTable.TABLE_NAME || ' WHERE date_rec >= add_months(sysdate, - ' || NB_MOIS_RETENTION || ')-1');
    		execute immediate 'create table DBDWAUTOUSR.TAB_TMP as select * from DBDWAUTOUSR.' || maTable.TABLE_NAME || ' WHERE date_rec >= add_months(sysdate, - ' || NB_MOIS_RETENTION || ')-1';
    		execute immediate 'truncate table DBDWAUTOUSR.' || maTable.TABLE_NAME ;
    		execute immediate 'insert /*+append */ into DBDWAUTOUSR. ' || maTable.TABLE_NAME || ' select * from DBDWAUTOUSR.TAB_TMP' ;
    		execute immediate 'drop table DBDWAUTOUSR.TAB_TMP purge' ;
    		update DBDWAUTOUSR.TMP_PURGE_ALL_TABLES set TABLE_NAME = maTable.TABLE_NAME;
    	end loop;
     
    	select count(*) into tbl_exist from all_tables where TABLE_NAME = 'TAB_TMP' and OWNER = 'DBDWAUTOUSR';
    	if tbl_exist = 1 then -- Si la table TMP existe alors...
    		delete from DBDWAUTOUSR.TMP_PURGE_ALL_TABLES;
    	end if;
     
    END DWAUTO_PURGE_ALL_TABLES;
    Par contre quelques chose m'interpelle, quand McM disait
    Ca veut dire que tout le traitement ne se fait que pour l'exception NO_DATA_FOUND, et le currTable ne sera donc jamais NULL, mais vaudra toujours ' '
    Qu'est ce que ça veut dire? Si ma requete à la ligne 11 retourne des valeurs, le traitement va bien s’exécuter non?
    J'ai oublié de préciser que ce n'est pas entièrement de moi. Je reprends le travail d'un traitement de purge d'un ancien collègue.
    De ce qu'on m'a dit il avait fait en sorte que la variable currTable ne soit jamais null car lorsue c'était le cas le traitement plantait pour X raison.
    Cordialement, le volatile!
    "Crôa, Crôa"

  8. #8
    Membre expérimenté Avatar de Cincinnatus
    Homme Profil pro
    Développeur d'applications métier
    Inscrit en
    Mars 2007
    Messages
    592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur d'applications métier
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2007
    Messages : 592
    Points : 1 679
    Points
    1 679
    Par défaut
    Citation Envoyé par Cvanhove Voir le message
    D'accord mais j'ai un doute, passer cette ligne en execute immediate me permet quand même d'alimenter ma variable cnt?
    C'est possible : d'après les exemples de chez Oracle : https://docs.oracle.com/cd/B12037_01...3_elems017.htm
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    DECLARE   sql_stmt    VARCHAR2(200);
       plsql_block VARCHAR2(500);
       emp_id      NUMBER(4) := 7566;
       salary      NUMBER(7,2);
       dept_id     NUMBER(2) := 50;
       dept_name   VARCHAR2(14) := 'PERSONNEL';
       location    VARCHAR2(13) := 'DALLAS';
       emp_rec     emp%ROWTYPE;
    BEGIN
       EXECUTE IMMEDIATE 'CREATE TABLE bonus (id NUMBER, amt NUMBER)';
       sql_stmt := 'INSERT INTO dept VALUES (:1, :2, :3)';
       EXECUTE IMMEDIATE sql_stmt USING dept_id, dept_name, location;
       sql_stmt := 'SELECT * FROM emp WHERE empno = :id';
       EXECUTE IMMEDIATE sql_stmt INTO emp_rec USING emp_id;
       plsql_block := 'BEGIN emp_pkg.raise_salary(:id, :amt); END;';
       EXECUTE IMMEDIATE plsql_block USING 7788, 500;
       sql_stmt := 'UPDATE emp SET sal = 2000 WHERE empno = :1
          RETURNING sal INTO :2';
       EXECUTE IMMEDIATE sql_stmt USING emp_id RETURNING INTO salary;
       EXECUTE IMMEDIATE 'DELETE FROM dept WHERE deptno = :num'
          USING dept_id;
       EXECUTE IMMEDIATE 'ALTER SESSION SET SQL_TRACE TRUE'; END;
    ça pourrait donner :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    execute immediate 'select count(*) from DBDWAUTOUSR.' || maTable || '.' || TABLE_NAME ||''' into cnt ;
    Ou d'autres versions avec les paramètres dans la requête, en utilisant le USING, à voir.

  9. #9
    Membre chevronné
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Février 2012
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : Distribution

    Informations forums :
    Inscription : Février 2012
    Messages : 652
    Points : 1 878
    Points
    1 878
    Par défaut
    Ce dont fait référence McM c'est que :
    - La grande partie de votre code se trouve dans le bloc d'exception NO_DATA_FOUND. Donc si une donnée est trouvée dans DBDWAUTOUSR.TMP_PURGE_ALL_TABLES, aucune instruction ne sera exécutée car cela mène à la fin de votre procédure
    - Si aucune donnée n'est trouvée, la variable currTable est forcée à blanc puis un test est réalisé pour savoir si elle est NULL ce qui ne sera jamais le cas


    Voici votre code indenté de façon plus lisible
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    create or replace procedure  DWAUTO_PURGE_ALL_TABLES(NB_MOIS_RETENTION number)
    is
      maTable varchar2(30 char);
      TABLE_NAME varchar2(100 char);
      nbEnr integer;
      currTable varchar2(30 char);
      tbl_exist varchar2(30 char);
      cnt integer;
     
    BEGIN
      select TABLE_NAME into currTable from DBDWAUTOUSR.TMP_PURGE_ALL_TABLES;
    EXCEPTION 
      WHEN no_data_found THEN
        currTable := ' ';
        if currTable is null then
          ---init avec une chaine vide pour traiter toutes les tables
          insert into DBDWAUTOUSR.TMP_PURGE_ALL_TABLES values (currTable);
        end if;
     
        for maTable in (select distinct substr(TABLE_NAME,1,16) as TABLE_NAME from all_tables where (REGEXP_like(TABLE_NAME,'^M[0-9]{6}_S[0-9]{7}$') or TABLE_NAME='MSG') AND OWNER = 'DBDWAUTOUSR' AND TABLE_NAME > currTable order by 1) loop
     
          select count(*) into tbl_exist from all_tables where TABLE_NAME = 'TAB_TMP' and OWNER = 'DBDWAUTOUSR';
          if tbl_exist = 1 then -- Si la table TMP existe alors...
            execute immediate 'select count(*) into cnt from DBDWAUTOUSR.' || maTable.TABLE_NAME;
            if cnt != 0 then -- Si la table source n'est pas vide, on Drop la table TMP
              execute immediate 'drop table DBDWAUTOUSR.TAB_TMP';
            end if; -- Sinon on skip le Drop de la table TMP et on passe à la suite
          end if;
     
          dbms_output.put_line( 'create table DBDWAUTOUSR.TAB_TMP as select * from DBDWAUTOUSR.' || maTable.TABLE_NAME || ' WHERE date_rec >= add_months(sysdate, - ' || NB_MOIS_RETENTION || ')-1');
          execute immediate 'create table DBDWAUTOUSR.TAB_TMP as select * from DBDWAUTOUSR.' || maTable.TABLE_NAME || ' WHERE date_rec >= add_months(sysdate, - ' || NB_MOIS_RETENTION || ')-1';
          execute immediate 'truncate table DBDWAUTOUSR.' || maTable.TABLE_NAME ;
          execute immediate 'insert /*+append */ into DBDWAUTOUSR. ' || maTable.TABLE_NAME || ' select * from DBDWAUTOUSR.TAB_TMP' ;
          execute immediate 'drop table DBDWAUTOUSR.TAB_TMP purge' ;
          update DBDWAUTOUSR.TMP_PURGE_ALL_TABLES set TABLE_NAME = maTable.TABLE_NAME;
        end loop;
     
        select count(*) into tbl_exist from all_tables where TABLE_NAME = 'TAB_TMP' and OWNER = 'DBDWAUTOUSR';
        if tbl_exist = 1 then -- Si la table TMP existe alors...
          delete from DBDWAUTOUSR.TMP_PURGE_ALL_TABLES;
        end if;
    END DWAUTO_PURGE_ALL_TABLES;

  10. #10
    Membre régulier Avatar de Cvanhove
    Homme Profil pro
    Concepteur Développeur Informatique
    Inscrit en
    Septembre 2014
    Messages
    174
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Deux Sèvres (Poitou Charente)

    Informations professionnelles :
    Activité : Concepteur Développeur Informatique

    Informations forums :
    Inscription : Septembre 2014
    Messages : 174
    Points : 70
    Points
    70
    Par défaut
    Effectivement je comprend mieux, j'ai vraiment du mal à lire le pl sql et je m'en excuse.

    J'ai pris note de vos remarques et voici enfin ce que donne la procédure (ce qui devrait être plus logique) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    create or replace procedure  DWAUTO_PURGE_ALL_TABLES(NB_MOIS_RETENTION number)
    is
    maTable varchar2(30 char);
    TABLE_NAME varchar2(100 char);
    nbEnr integer;
    currTable varchar2(30 char);
    tbl_exist varchar2(30 char);
    cnt integer;
    sql_stmt    VARCHAR2(200);
     
    BEGIN
        BEGIN
        select TABLE_NAME into currTable from DBDWAUTOUSR.TMP_PURGE_ALL_TABLES;
        EXCEPTION WHEN no_data_found THEN
            currTable := ' ';
        END;    
        BEGIN
            if currTable is null then
                ---init avec une chaine vide pour traiter toutes les tables
                insert into DBDWAUTOUSR.TMP_PURGE_ALL_TABLES values (currTable);
            end if;
     
            for maTable in (select distinct substr(TABLE_NAME,1,16) as TABLE_NAME from all_tables where (REGEXP_like(TABLE_NAME,'^M[0-9]{6}_S[0-9]{7}$') or TABLE_NAME='MSG') AND OWNER = 'DBDWAUTOUSR' AND TABLE_NAME > currTable order by 1) loop
     
                select count(*) into tbl_exist from all_tables where TABLE_NAME = 'TAB_TMP' and OWNER = 'DBDWAUTOUSR';
                if tbl_exist = 1 then -- Si la table TMP existe alors...
                    sql_stmt := 'select count(*) from DBDWAUTOUSR.' || maTable.TABLE_NAME;
                    execute immediate sql_stmt into cnt ;
                    if cnt != 0 then -- Si la table source n'est pas vide, on Drop la table TMP
                        execute immediate 'drop table DBDWAUTOUSR.TAB_TMP';
                    end if; -- Sinon on skip le Drop de la table TMP et on passe à la suite
                end if;
     
                dbms_output.put_line( 'create table DBDWAUTOUSR.TAB_TMP as select * from DBDWAUTOUSR.' || maTable.TABLE_NAME || ' WHERE date_rec >= add_months(sysdate, - ' || NB_MOIS_RETENTION || ')-1');
                execute immediate 'create table DBDWAUTOUSR.TAB_TMP as select * from DBDWAUTOUSR.' || maTable.TABLE_NAME || ' WHERE date_rec >= add_months(sysdate, - ' || NB_MOIS_RETENTION || ')-1';
                execute immediate 'truncate table DBDWAUTOUSR.' || maTable.TABLE_NAME ;
                execute immediate 'insert /*+append */ into DBDWAUTOUSR. ' || maTable.TABLE_NAME || ' select * from DBDWAUTOUSR.TAB_TMP' ;
                execute immediate 'drop table DBDWAUTOUSR.TAB_TMP purge' ;
                update DBDWAUTOUSR.TMP_PURGE_ALL_TABLES set TABLE_NAME = maTable.TABLE_NAME;
            end loop;
     
            select count(*) into tbl_exist from all_tables where TABLE_NAME = 'TAB_TMP' and OWNER = 'DBDWAUTOUSR';
            if tbl_exist = 1 then -- Si la table TMP existe alors...
                delete from DBDWAUTOUSR.TMP_PURGE_ALL_TABLES;
            end if;
        END;
    END DWAUTO_PURGE_ALL_TABLES;
    Cordialement, le volatile!
    "Crôa, Crôa"

  11. #11
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Il reste quelques problèmes mineurs de typages de données, et j'aime bien préfixer les variables, paramètres et curseurs par respectivement v$, p$ et c$ de manière à les reconnaître directement.
    Enfin un dernier effort d'indentation rend le code, à mon sens, plus lisible :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    create or replace procedure DWAUTO_PURGE_ALL_TABLES (p$_NB_MOIS_RETENTION number)
    is
        v$_currTable                     varchar2( 30 char);
        v$_tbl_exist                     simple_integer := 0;
        v$_cnt                           simple_integer := 0;
        v$_sql_stmt                      varchar2(200);
        v$_NB_MOIS_RETENTION    constant varchar2(  3) := to_char(p$_NB_MOIS_RETENTION, 'fm990');
     
    begin
        begin
            select TABLE_NAME
              into v$_currTable
              from DBDWAUTOUSR.TMP_PURGE_ALL_TABLES;
     
        exception when no_data_found
            then v$_currTable := ' ';
        end;
     
        begin
            if v$_currTable is null then
                ---init avec une chaine vide pour traiter toutes les tables
                insert into DBDWAUTOUSR.TMP_PURGE_ALL_TABLES (TABLE_NAME) values (null);
            end if;
     
            for c$_maTable in
            (
              select distinct
                     substr(TABLE_NAME, 1, 16) as TABLE_NAME
                from ALL_TABLES
               where (TABLE_NAME = 'MSG' or regexp_like(TABLE_NAME,'^M[0-9]{6}_S[0-9]{7}$'))
                 and OWNER       = 'DBDWAUTOUSR'
                 and TABLE_NAME  > v$_currTable
            order by 1
            )
            loop
     
                select count(*)
                  into v$_tbl_exist
                  from ALL_TABLES
                 where TABLE_NAME = 'TAB_TMP'
                   and OWNER      = 'DBDWAUTOUSR';
     
                if v$_tbl_exist = 1 then -- Si la table TMP existe alors...
                    v$_sql_stmt := 'select count(*) from DBDWAUTOUSR.' || c$_maTable.TABLE_NAME;
                    execute immediate v$_sql_stmt into v$_cnt;
     
                    if v$_cnt > 0 then -- Si la table source n'est pas vide, on Drop la table TMP
                        execute immediate 'drop table DBDWAUTOUSR.TAB_TMP';
                    end if; -- Sinon on skip le Drop de la table TMP et on passe à la suite
                end if;
     
                v$_sql_stmt := 'create table DBDWAUTOUSR.TAB_TMP as select * from DBDWAUTOUSR.'
                            || c$_maTable.TABLE_NAME
                            || ' where date_rec >= add_months(sysdate, -' || v$_NB_MOIS_RETENTION || ')-1';
                dbms_output.put_line(v$_sql_stmt);
                execute immediate v$_sql_stmt;
     
                execute immediate 'truncate table DBDWAUTOUSR.' || c$_maTable.TABLE_NAME;
                execute immediate 'insert /*+ append */ into DBDWAUTOUSR. ' || c$_maTable.TABLE_NAME || ' select * from DBDWAUTOUSR.TAB_TMP';
                execute immediate 'drop table DBDWAUTOUSR.TAB_TMP purge';
     
                update DBDWAUTOUSR.TMP_PURGE_ALL_TABLES
                   set TABLE_NAME = c$_maTable.TABLE_NAME;
     
            end loop;
     
            select count(*)
              into v$_tbl_exist
              from ALL_TABLES
             where TABLE_NAME = 'TAB_TMP'
               and OWNER      = 'DBDWAUTOUSR';
     
            if v$_tbl_exist = 1 then -- Si la table TMP existe alors...
                delete from DBDWAUTOUSR.TMP_PURGE_ALL_TABLES;
            end if;
        end;
     
    end DWAUTO_PURGE_ALL_TABLES;
    /

  12. #12
    Membre régulier Avatar de Cvanhove
    Homme Profil pro
    Concepteur Développeur Informatique
    Inscrit en
    Septembre 2014
    Messages
    174
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Deux Sèvres (Poitou Charente)

    Informations professionnelles :
    Activité : Concepteur Développeur Informatique

    Informations forums :
    Inscription : Septembre 2014
    Messages : 174
    Points : 70
    Points
    70
    Par défaut
    Merci infiniment pour vos retours et l'aide apporter
    Cordialement, le volatile!
    "Crôa, Crôa"

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Condition dans une requete (pas en SQL)
    Par Luc01 dans le forum Requêtes et SQL.
    Réponses: 8
    Dernier message: 08/12/2006, 22h57
  2. utilisation de la requete select de sql
    Par pepper18 dans le forum SGBD
    Réponses: 3
    Dernier message: 31/05/2006, 15h01
  3. Creation de Requete Croisée sous SQL Server 2K
    Par Fabby69 dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 27/08/2005, 17h14
  4. Portage requete Access vers SQL Server (Iif)...
    Par cmousset dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 14/06/2005, 16h38
  5. REquete sans erreur sql qui n'agit pas ........
    Par Skam dans le forum Langage SQL
    Réponses: 7
    Dernier message: 02/02/2005, 13h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo