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

SQL Oracle Discussion :

[PL/SQL] Parseur de requête [Sources]


Sujet :

SQL Oracle

  1. #1
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut [PL/SQL] Parseur de requête
    Bonjour,

    Quelqu'un a t-il dans ses cartons un code PL/SQL permettant de parser une requête SQL ?

    c'est à dire d'analyser un ordre Select et d'en ressortir la liste des colonnes qui le constitue ?

  2. #2
    Membre expérimenté

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2003
    Messages : 412
    Points : 1 326
    Points
    1 326
    Par défaut
    Je comprends ce que tu veux dire mais je vois pas trop ce que cela devrait te resortir.

    Tu veux un code PL/SQL qui quand tu lui donne un ordre select te resorte les colonnes utilisé dans la clause select????

  3. #3
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    Oui exactement. Et pour ce faire je ne peux pas tricher en créant une vue ou une table pour en extraire les colonnes....
    Il me faut donc un analyseur qui sache se dépatouiller de trucs du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Select * from (select x "aliasx", y from .... ) ...

  4. #4
    Membre expérimenté

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2003
    Messages : 412
    Points : 1 326
    Points
    1 326
    Par défaut
    Oki je regarde si je peux te faire ca rapidement.

  5. #5
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    Et bien, pour ne rien te cacher, cela m'enlèverait un poteau télégraphique du pied !!!

  6. #6
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    ouch... alors là c'est fort de fort... j'crois que je vais tenter aussi de relever le défis

    aller hop... au boulot

  7. #7
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    Merci pour ces chaleureux témoignages de trituration de matière grise les gars.
    D'habitude je suis le premier à m'y coller, mais pour le coup, j'ai trop d'autres portions de code à décerveller en peu de temps...

  8. #8
    Membre expérimenté

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2003
    Messages : 412
    Points : 1 326
    Points
    1 326
    Par défaut
    tiens regarde avec ca...

    Ca te renvoie une table pl/sql contenant les différentes colonnes (c un peu lent vu que je vais chercher dans all_tab_columns

    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
    FUNCTION parse_sql(p_requete VARCHAR2) RETURN owa_text.vc_arr IS
        v_mot        owa_text.vc_arr;
        v_pos_espace NUMBER;
        v_cpt        NUMBER := 1;
        v_requete    VARCHAR2(32676) := p_requete;
        v_owner      VARCHAR2(50);
        v_name       VARCHAR2(50);
        CURSOR cur_col(p_name VARCHAR2) IS
          SELECT owner || '.' || column_name
          FROM   all_tab_columns
          WHERE  column_name = upper(p_name);
        CURSOR cur_col2(p_name VARCHAR2, p_owner VARCHAR2) IS
          SELECT owner || '.' || column_name
          FROM   all_tab_columns
          WHERE  column_name = upper(p_name) AND owner = upper(p_owner);
        v_colonne VARCHAR2(200);
        t_col     owa_text.vc_arr;
      BEGIN
        -- On recherche le premier espace
        v_pos_espace := instr(v_requete, ' ');
        LOOP
          EXIT WHEN v_pos_espace = 0;
          --On extrait le premier mot
          v_mot(v_cpt) := REPLACE(substr(v_requete, 1, v_pos_espace), ' ', '');
          v_cpt := v_cpt + 1;
          v_requete := substr(v_requete, v_pos_espace + 1);
          v_pos_espace := instr(v_requete, ' ');
        END LOOP;
        v_mot(v_cpt) := v_requete;
        v_cpt := 1;
        FOR i IN 1 .. v_mot.COUNT LOOP
          -- On ne tiens pas compte des mots clé standard
          IF lower(v_mot(i)) NOT IN
             ('select', 'from', 'where', 'group', 'by', 'order', 'having', '(', ')') THEN
            -- on vérifie si y a un point à l'interieur du mot
            IF instr(v_mot(i), '.') = 0 THEN
              OPEN cur_col(v_mot(i));
              FETCH cur_col
                INTO v_colonne;
              CLOSE cur_col;
            ELSE
              v_owner := substr(v_mot(i), 1, instr(v_mot(i), '.'));
              v_name  := substr(v_mot(i), instr(v_mot(i), '.') + 1);
              OPEN cur_col2(v_name, v_owner);
              FETCH cur_col2
                INTO v_colonne;
              CLOSE cur_col2;
            END IF;
            --on enregistre le nom de la colonne 
            IF v_colonne IS NOT NULL THEN
              t_col(v_cpt) := v_colonne;
              v_cpt := v_cpt + 1;
              v_colonne := NULL;
            END IF;
          END IF;
        END LOOP;
    return t_col;
      END;

  9. #9
    Membre expérimenté

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2003
    Messages : 412
    Points : 1 326
    Points
    1 326
    Par défaut
    Je peux compliquer apres en faisant une recherche sur les tables contenues dans la requete mais comme tu as pas précisé

  10. #10
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    Diantre, quelle vélocité !!
    j'essaie le matos.
    Le select dans les vues système implique que les bidouilles de type :

    select col * 2 "comptage" ne passera pas ?

  11. #11
    Membre expérimenté

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2003
    Messages : 412
    Points : 1 326
    Points
    1 326
    Par défaut
    Alors sur ton exemple de requete il ne te retournera que le col

  12. #12
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    j'ai fait plus simple :

    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
    declare
      stmt VARCHAR2(2000);
      c number;
      d number;
      col_cnt integer;
      f boolean;
      rec_tab dbms_sql.desc_tab2;
      rec_desc dbms_sql.desc_rec2;
      col_num number;
    begin
      c := dbms_sql.open_cursor;
      stmt  :=  'select * from matable';
      dbms_sql.parse(c,stmt, DBMS_SQL.NATIVE);
     
      d := dbms_sql.execute(c);
     
      dbms_sql.describe_columns2(c, col_cnt, rec_tab);
     
    /*
     * Following loop could simply be for j in 1..col_cnt loop.
     * Here we are simply illustrating some of the PL/SQL table
     * features.
     */
      col_num := rec_tab.first;
      if (col_num is not null) then
        loop
        dbms_output.put_line('col_name            =    '
                             || rec_tab(col_num).col_name);
          col_num := rec_tab.next(col_num);
          exit when (col_num is null);
        end loop;
      end if;
     
      dbms_sql.close_cursor(c);
    end;
    /
    Voila comment j'ai trouvé

    http://download-west.oracle.com/docs/cd/B10501_01/appdev.920/a96612/d_sql.htm#1006465

  13. #13
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    A noter que describe_columns est buggé d'où l'utilisation de describe_columns2

  14. #14
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    Citation Envoyé par helyos
    Alors sur ton exemple de requete il ne te retournera que le col
    cela fonctionne parfaitement sur la requête de type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select * from (select code from p_periodes where statut_stat=''O'' order by exercice_code desc, numero desc)
    Je vais virer le nom du OWNER récupéré dans la collection et prendre en compte de préférence les alias s'ils sont indiqués dans la requête.

    Super !! et merci

    je m'en vais du même coup tester la propal d' orafrance.

  15. #15
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    si ma requête ne marche pas ... bah j'aurais quand même appris un sacré truc avec DBMS_SQL

    Et bravo à helyos qui décidemment est une star du PL/SQL

  16. #16
    Membre expérimenté

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2003
    Messages : 412
    Points : 1 326
    Points
    1 326
    Par défaut
    LOL merci par contre la méthode d'orafrance sera plus performante sur une requete de type SELECT * sans clause where (vu que ca execute le code, plus besoin de regarder si c une colonne connue comme dans mon code)

    Bravo à toi aussi orafrance

  17. #17
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    Citation Envoyé par orafrance
    si ma requête ne marche pas ... bah j'aurais quand même appris un sacré truc avec DBMS_SQL

    Et bravo à helyos qui décidemment est une star du PL/SQL
    Ta requête fonctionne parfaitement, cher orafrance et de surcroit prend en compte les alias ! c'est du caviard !!!

    Merci à vous deux, vous venez effectivement de m' enlever un poteau télégraphique du pied !!!

    A charge de revanche.

  18. #18
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    Et bien c'est génial

    Quand au poteau, attention où tu le mets

  19. #19
    Membre expérimenté

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2003
    Messages : 412
    Points : 1 326
    Points
    1 326
    Par défaut
    et elle est ou la balise résolu???

  20. #20
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    Benff, cmouf'étais en train, chlourmpf, de finir ma bouchée, shlurpf, de caviar, groumpf.....

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

Discussions similaires

  1. [Oracle] [SQL] problème de requête
    Par joselito dans le forum PHP & Base de données
    Réponses: 24
    Dernier message: 25/01/2006, 12h55
  2. [SQL]problème de requête.
    Par shnouf dans le forum Oracle
    Réponses: 21
    Dernier message: 24/01/2006, 11h12
  3. [SQL] Aide pour requête
    Par portu dans le forum Access
    Réponses: 8
    Dernier message: 23/09/2005, 13h05
  4. [SQL] Problème de requête SQL de plus de 8060 caractères ?
    Par webtheque dans le forum MS SQL Server
    Réponses: 13
    Dernier message: 06/04/2005, 15h07
  5. Affecter résultat SQL d'une requête à une variable
    Par bozolozo dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 02/01/2005, 17h37

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