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 :

Fonction PL/SQL sans connaître la table


Sujet :

PL/SQL Oracle

  1. #1
    Membre du Club
    Inscrit en
    Août 2010
    Messages
    78
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 78
    Points : 63
    Points
    63
    Par défaut Fonction PL/SQL sans connaître la table
    Bonjour à tout le monde ,


    Svp si vous pouvez me dire : Est ce que c'est possible de créer une fonction PL SQL qui prend en IN une requête select dynamique ( sous type String ) et elle me retourne résultat ..Sachant que je ne connais ni la table ni le nombre de ses colonnes ..


    Merci d'avance

  2. #2
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Si tu ne connais pas le nombre de colonnes, tu ne peux pas donner un type de retour à ta fonction de toute manière.

    Pour les autre cas, tu peux utiliser

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    execute immediat "requete" bulk collect into t_resultat
    avec t_resultat de type table of [ton retour]

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

  3. #3
    Membre confirmé
    Avatar de Bibeleuh
    Homme Profil pro
    Développeur
    Inscrit en
    Septembre 2010
    Messages
    209
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bas Rhin (Alsace)

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

    Informations forums :
    Inscription : Septembre 2010
    Messages : 209
    Points : 542
    Points
    542
    Par défaut
    Salut,

    Tu cherches à exécuter une requête passée en paramètre si j'ai bien compris, tu peux essayer avec ce bout de code :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    FUNCTION execute_query (queryString IN VARCHAR2 , messageErreur OUT VARCHAR2) RETURN NUMBER IS
     
    BEGIN
        EXECUTE IMMEDIATE queryString;
     
        RETURN 1;
     
        EXCEPTION WHEN OTHERS THEN
            messageErreur := SQLERRM;
            RETURN 0;    
    END execute_query;
    Qui te retourne 1 si la requête s'est bien exécutée, 0 sinon et tu peux récupérer le message d'erreur dans le paramètre messageErreur

  4. #4
    Membre du Club
    Inscrit en
    Août 2010
    Messages
    78
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 78
    Points : 63
    Points
    63
    Par défaut
    Une requête Select et récupérer son retour ..

  5. #5
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Citation Envoyé par ayoubkira Voir le message
    Une requête Select et récupérer son retour ..
    cf. réponse supra.

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

  6. #6
    Membre confirmé
    Avatar de Bibeleuh
    Homme Profil pro
    Développeur
    Inscrit en
    Septembre 2010
    Messages
    209
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bas Rhin (Alsace)

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

    Informations forums :
    Inscription : Septembre 2010
    Messages : 209
    Points : 542
    Points
    542
    Par défaut
    Citation Envoyé par ayoubkira Voir le message
    Une requête Select et récupérer son retour ..

    Ok désolé, j'ai pas vu que c'était pour une instruction select...
    Je crois que Bluedeep a répondu à ta question du coup

  7. #7
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Détaillez ce que vous cherchez avec un exemple.
    C'est possible via des ref cursors ou via des fonctions pipelined par exemple.

  8. #8
    Membre du Club
    Inscrit en
    Août 2010
    Messages
    78
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 78
    Points : 63
    Points
    63
    Par défaut
    Supposons que j'ai une requete Select * from uneTable ( sans connaitre les colonnes de cette table )

    je veux recuperer toutes les lignes et de plus je veux que chaque ligne sera affectée à une variable String de telle sorte les colonnes seront séparés par , .

    Par exemple :

    VariableString= col1 ,col2,col3,..

  9. #9
    Membre expert
    Avatar de Sunchaser
    Homme Profil pro
    OPNI (Objet Programmant Non Identifié)
    Inscrit en
    Décembre 2004
    Messages
    2 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : OPNI (Objet Programmant Non Identifié)
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 059
    Points : 3 204
    Points
    3 204
    Par défaut
    Bonjour,
    Si la requête t'es passée toute entière en paramètre, il te faut alors:
    . analyser la chaîne pour trouver la clause FROM et la table concernée,
    . regarder dans all_tab_columns - par exemple - pour lister les colonnes et générer la partie du "select" avec la concaténation que tu veux faire (
    col1 ,col2,col3,..
    )
    . retravailler si besoin le SQL qui t'était passé en paramètre afin de mettre a la place du "select" d'origine le tiens, celui avec la concaténation, tout en conservant le "from" et le "where" d'origine,
    . ensuite exécution dynamique, fetch cursor et renvoyer le tout sous forme de varchar2, ou "table of varchar2..."

    @+
    Aux persévérants aucune route n'est interdite.
    Celui qui ne sait pas se contenter de peu ne sera jamais content de rien.
    Current Status
    Avec 40% de pollinisateurs invertébrés menacés d'extinction selon les Nations Unies, l'homme risque fort de passer de la monoculture à la mono diète...
    Faîtes quelque chose de bien avec vos petits sous: Enfants du Mekong

  10. #10
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Citation Envoyé par Sunchaser Voir le message
    Bonjour,
    Si la requête t'es passée toute entière en paramètre, il te faut alors:
    . analyser la chaîne pour trouver la clause FROM et la table concernée,
    . regarder dans all_tab_columns - par exemple - pour lister les colonnes et générer la partie du "select" avec la concaténation que tu veux faire ()
    Euh .... utiliser la procedure PARSE du package DBMS_SQL est peut être plus simple, non ?

    Ensuite utiliser les procedure COLUMN_VALUE, ce devrait être possible non ?

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

  11. #11
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Dans ce cas utilisez DBMS_SQL.
    Des nombreux exemples existe dans la doc, sur le site de Tom Kyte et ailleurs.

  12. #12
    Membre expert
    Avatar de Sunchaser
    Homme Profil pro
    OPNI (Objet Programmant Non Identifié)
    Inscrit en
    Décembre 2004
    Messages
    2 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : OPNI (Objet Programmant Non Identifié)
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 059
    Points : 3 204
    Points
    3 204
    Par défaut
    Citation Envoyé par Bluedeep Voir le message
    Euh .... utiliser la procedure PARSE du package DBMS_SQL est peut être plus simple, non ?

    Ensuite utiliser les procedure COLUMN_VALUE, ce devrait être possible non ?
    Tout a fait, désolé.
    Je suis allé trop vite.

    @+
    Aux persévérants aucune route n'est interdite.
    Celui qui ne sait pas se contenter de peu ne sera jamais content de rien.
    Current Status
    Avec 40% de pollinisateurs invertébrés menacés d'extinction selon les Nations Unies, l'homme risque fort de passer de la monoculture à la mono diète...
    Faîtes quelque chose de bien avec vos petits sous: Enfants du Mekong

  13. #13
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Bonjour

    Bon, j'avais 5mn, donc un petit exemple torché vite fait, qui ne supporte que des colonnes 'varchar2' mais qui peut (et doit) être adapté.

    Création de la table et des données :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    CREATE
      TABLE PARSE_TEST
      (
        COLUMN1 VARCHAR2(100 BYTE),
        COLUMN2 VARCHAR2(100 BYTE)
      );
     
    insert into parse_test values ('1abdefghijk', 'lmnopqrstu1');
    insert into parse_test values ('2abdefghijk', 'lmnopqrstu2');
    insert into parse_test values ('3abdefghijk', 'lmnopqrstu3');
    Execution dynamique d'un select '*' avec concaténation des colonnes de chaque ligne :


    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
    declare
      v_ret varchar2(500);
      v_sql varchar2(100) := 'select * from parse_test'; -- requête dynamique 
      v_cursor pls_integer;
      v_col_count pls_integer;
      v_row_count pls_integer;
      v_desc_t dbms_sql.DESC_TAB;
      v_col_value varchar2(100);
      v_irow pls_integer := 0;
    begin
      v_cursor := dbms_sql.open_cursor;
     
      dbms_sql.parse(v_cursor, v_sql, DBMS_SQL.NATIVE);
     
      /* récupération du nombre de colonnes et définition => ici on ne traite que du varchar pour démo */
      dbms_sql.describe_columns(v_cursor, v_col_count, v_desc_t);
      dbms_output.put_line('Nbr de colonnes ' || to_char(v_col_count));
      for icol in 1..v_col_count
      loop
       /* affichage nom de chaque colonne, type et long. maxi  */
        dbms_output.put_line ('Nom colonne ' || to_char(icol) || 
                                ' : ' || v_desc_t(icol).col_name ||
                                ' Type ' || to_char(v_desc_t(icol).col_type) ||
                                ' Len ' ||  to_char(v_desc_t(icol).col_max_len));
     
        /* ici "en vrai" il faudrait regarder le détail de chaque colonne dans v_desc_t 
        pour les besoins de la demo on considère varchar2(100) */
        DBMS_SQL.DEFINE_COLUMN (v_cursor, icol, v_col_value, 100);
      end loop;
     
      /* exécution de la requête et fetch première ligne */
      v_row_count := dbms_sql.execute_and_fetch(v_cursor);  
     
     while v_row_count <> 0
      loop  
        v_irow := v_irow + 1;
        v_ret := '';
        dbms_output.put_line('Ligne N° ' || to_char(v_irow));
        /* concaténation des colonnes de la ligne */
        for Icol in 1..v_col_count    
        loop
          dbms_sql.column_value(v_cursor, Icol, v_col_value);
          if v_ret is not null then
            v_ret := v_ret || ',';
          end if;
          v_ret := v_ret || v_col_value;
        end loop;    
        dbms_output.put_line('resultat concat colonnes ligne N° ' || v_irow || ' : ' || v_ret);
        /* ligne suivante */
        v_row_count := dbms_sql.fetch_rows(v_cursor);
      end loop;
      dbms_sql.close_cursor(v_cursor);
     
    end;

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

Discussions similaires

  1. Trouver une valeur sans connaître la table
    Par Passepoil dans le forum Langage SQL
    Réponses: 3
    Dernier message: 22/07/2010, 15h47
  2. Réponses: 6
    Dernier message: 12/04/2010, 15h53
  3. [MySQL] problème de fonction SQL pour modification de table
    Par Purple Haze dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 27/02/2007, 17h00
  4. Réponses: 2
    Dernier message: 04/09/2006, 18h07
  5. [SQL SERVER 2000] Fonction utilisateur : boucle sans fin
    Par galinijay dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 30/09/2005, 16h03

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