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 :

SQL Dynamique pour listes de taille variable


Sujet :

SQL Oracle

  1. #1
    Membre du Club
    Inscrit en
    Janvier 2007
    Messages
    50
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 50
    Points : 40
    Points
    40
    Par défaut SQL Dynamique pour listes de taille variable
    Bonjour,

    j'ai un problème en PL/SQL et j'avoue que je commence à bloquer...

    J'aimerais pouvoir faire un truc du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE OR REPLACE FUNCTION MA_FONCTION(LST_VAL IN VARCHAR2) RETURN INTEGER IS
        CURSOR MON_CURS IS
            SELECT * FROM MA_TABLE WHERE MON_CHAMP IN (LST_VAL);
        ...
    BEGIN
        ...
    END;
    où le champ MON_CHAMP est de type NUMBER.
    En gros, je voudrais pouvoir interpréter la liste de nombre que je passe en paramètres sous forme de clause IN.

    Est-ce possible ? Si non, comment arriver à ce type de résultat, sachant que LST_VAL peut contenir un nombre variable de valeurs ? (Existe-t-il des fonctions PL/SQL avec un nombre d'arguments variable ?)

    Merci d'avance

  2. #2
    Membre averti
    Inscrit en
    Novembre 2002
    Messages
    549
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 549
    Points : 436
    Points
    436
    Par défaut
    Bonjour,

    je serai toi j'alimenterai une temporary table avec tes nombres, au préalable dans ta procédure stockée.
    si je te propose cette solution c'est que j'ai déjà lu plusieurs posts sur des pbs de perfs sur les listes + une limite il me semble à 50 items (à vérifier).

    @

  3. #3
    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
    en effet, la temporary table est trop souvent oubliée alors que c'est une solution qui peut s'avérer très performante

  4. #4
    Expert confirmé
    Avatar de laurentschneider
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Décembre 2005
    Messages
    2 944
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2005
    Messages : 2 944
    Points : 4 926
    Points
    4 926
    Par défaut
    une approche est d'utiliser une collection

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    create or replace type t_n as table of number;
    /
     
    create or replace function f (lst_val t_n) return number is 
    cursor c is select * from emp where empno member of lst_val;
    begin
    return 0;
    end;
    /
    ensuite tu peux faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    select f(t_n(1,2,3)) from dual;

  5. #5
    Expert confirmé
    Avatar de laurentschneider
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Décembre 2005
    Messages
    2 944
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2005
    Messages : 2 944
    Points : 4 926
    Points
    4 926
    Par défaut
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    create or replace function f (lst_val t_n) return number is 
    cursor c is select * from emp where empno in (
      select * from table(lst_val));
    begin
    return 0;
    end;
    /

  6. #6
    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
    Voir sans table intermédiaire:
    http://fdegrelle.over-blog.com/article-1694534.html

  7. #7
    Membre du Club
    Inscrit en
    Janvier 2007
    Messages
    50
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 50
    Points : 40
    Points
    40
    Par défaut
    Ouah !
    Tout d'abord merci à vous tous pour le nombre de réponses en si peu de temps !

    J'ai finalement utilisé la solution de SheikYerbouti sans table intermédiaire, car ce que je n'avais pas dit est que cette fonction doit être appelée depuis un module Java et que je ne voulais pas laisser de type défini dans la Base...

    J'ai donc implémenté 2 méthodes SPLIT() et DYNA_LISTE() que j'appelle pour transformer ma liste sous forme de VARCHAR2 en liste sys.dbms_debug_vc2coll

    Ca fonctionne correctement , mais je sens que c'est un peu 'de la bidouille'.

    J'aime bien la solution basée sur un type TABLE OF NUMBER mais je n'arrive pas à la mettre en place.
    L'idéal serait pour moi de commencer ma fonction par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TYPE MON_TYPE IS TABLE OF NUMBER
    puis de caster ma liste passée sous forme de VACHAR2 (obligé car appelé depuis Java) en MON_TYPE

    J'en suis là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    CREATE OR REPLACE FUNCTION MA_FONCTION(LST_VAL IN VARCHAR2) RETURN INTEGER IS
        TYPE MON_TYPE IS TABLE OF NUMBER
        CURSOR MON_CURS IS
            SELECT * FROM MA_TABLE WHERE MON_CHAMP IN (CAST(LST_VAL AS MON_TYPE));
        ...
    BEGIN
        ...
    END;
    J'ai une erreur de compilation, ce que je peux comprendre.
    Suis-je sur la bonne voie, ou dois-je abandonner cette solution ?

  8. #8
    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
    Autre solution simple vu que monchamp est un NUMBER :
    LST_VAL : doit être de la forme 'nb1;nb2;nb3...nb158'

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT * 
    FROM MA_TABLE 
    WHERE INSTR(';'|| MON_CHAMP || ';', ';'|| LST_VAL ||';') > 0;

  9. #9
    Membre du Club
    Inscrit en
    Janvier 2007
    Messages
    50
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 50
    Points : 40
    Points
    40
    Par défaut
    Pas mal !
    Ca fonctionne relativement vite en plus, ce qui est etonnant.

    Par contre j'ai juste corrigé l'ordre dans la requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT * 
    FROM MA_TABLE 
    WHERE INSTR(';'|| LST_VAL ||';', ';'|| MON_CHAMP || ';') > 0;
    Merci beaucoup à tous

  10. #10
    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
    Oops, écrit à l'arrache, comme d'hab..

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

Discussions similaires

  1. [astuce]sql dynamique pour l'interet des developpeur
    Par islamov2000 dans le forum Reports
    Réponses: 1
    Dernier message: 13/04/2013, 05h03
  2. sql dynamique pour l'interet des developpeur
    Par islamov2000 dans le forum Reports
    Réponses: 0
    Dernier message: 13/07/2011, 15h26
  3. [E-03] Liste déroulante, taille variable
    Par silmarion dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 30/09/2008, 22h14
  4. Réponses: 2
    Dernier message: 25/09/2007, 08h55
  5. [DB2] SQL dynamique pour déclarer un curseur
    Par Fatah93 dans le forum DB2
    Réponses: 3
    Dernier message: 12/12/2006, 13h06

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