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

DB2 Discussion :

Fonction pour caractère Joker


Sujet :

DB2

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 42
    Points : 31
    Points
    31
    Par défaut Fonction pour caractère Joker
    Bonjour à Tous,

    Juste un petit coup de main je pense qu'il ne s'agit pas de grand chose mais j'ai un petit soucis:
    voila j'ai créé la fonction ci dessous

    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
    create function BIB/fgesjoklt4(ST VARCHAR(3))           
    returns varchar(256)                                     
    language sql                                             
     
    deterministic                                            
    disallow parallel                                        
    no external action                                       
    Returns Null on Null Input                               
    begin                                                    
    declare etat varchar(256);                               
    set etat = ST;                                           
    If ST='*' or ST=''or ST='TOUT' then                      
    set  etat='''SO''' concat ',' concat ''' VA''' concat ','
    concat ''' ES''';                                        
    end if;                                                  
    return etat;                                             
    end
    losrque je la teste

    select * from prod.doslief where dosgqdo in (BIB.FGESJOKLT4('ES'))
    cela me ramène des valeurs
    de même si je fais:
    select * from prod.doslief where dosgqdo in ('ES', 'VA' ,'SO')

    mais si je fais
    select * from prod.doslief where dosgqdo in (BIB.FGESJOKLT4('TOUT'))
    la requête ne me ramène rien (même pas un code erreur )
    est ce que vous voyez ou ai je bien pu me tromper?

    Je vous remercie d'avance pour toute aide.

    Couf

  2. #2
    Membre expérimenté

    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 298
    Points : 1 578
    Points
    1 578
    Par défaut
    create function BIB/fgesjoklt4(ST VARCHAR(4))

    "TOUT" fait 4 caractères de long...

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 42
    Points : 31
    Points
    31
    Par défaut
    Salut Philippe

    si je fais select * from prod.doslief where dosgqdo in (BIB.FGESJOKLT4(char(*))
    J'obtient aussi le même résultat

  4. #4
    Membre expérimenté

    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 298
    Points : 1 578
    Points
    1 578
    Par défaut
    A regarder ta requête de plus près, en employant la fonction FGESJOKLT4 sur le prédicat WHERE, je me rends compte maintenant que sa formulation est erronée. En effet, si tu indiques
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WHERE dosgqdo in (BIB.FGESJOKLT4('*'))
    cela veut dire que tu compares la valeur de la colonne dosgqdo directement avec la valeur litérale " '''SO'','' VA'','' ES''' " et non pas avec la liste des valeurs '''SO'','' VA'','' ES''' comme tu l'espères. Toutefois, la requête fonctionne correctement si tu indiques
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WHERE dosgqdo in (BIB.FGESJOKLT4('ES'))
    car la fonction dans ce cas renvoie la valeur "ES" et le colonne dosgqdo contient la valeur "ES". Cela revient au même que de tester l'égalité Idem probablement pour "SO" et "VA".

    Tu ne peux pas renvoyer une liste des valeurs dans un seul paramètre. Pour faire ce genre de chose, il faut que tu emploies autant de paramètres qu'il y a de valeurs dans la liste, et ça, tu ne peux pas le faire par une simple fonction scalaire qui n'accepte qu'une seule valeur en retour.

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 42
    Points : 31
    Points
    31
    Par défaut
    Bonjour
    Ok je cromprends mieux mon erreur
    donc le mieux serait de faire un truc de ce genre
    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
    create function BIB/fgesjoklt5(ST VARCHAR(4))            
    returns varchar(256)                                      
    language sql                                              
    deterministic                                             
    disallow parallel                                         
    no external action                                        
    Returns Null on Null Input                                
    begin                                                     
    declare etat varchar(256);                                
    set etat = ST;                                            
    If ST='*' or ST=''or ST='TOUT' then return                
    (select dosgqdo from prod/doslief group by dosgqdo); 
    else return etat;                                         
    end if;                                                   
    end
    a part que j'ai une petite erreur ou je vais devoir employé des cursuers pour l'instant mais si tu me confirmes que cela pourrais mieux marché
    PS: si tu as un tuyau (s'il te plait) pour les cursuers je suis preneur
    merci d'avance

  6. #6
    Membre expérimenté

    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 298
    Points : 1 578
    Points
    1 578
    Par défaut
    Citation Envoyé par couf35
    ...donc le mieux serait de faire un truc de ce genre...
    Non car même si tu arrivais à mettre au point ta fonction avec ton "select group by", ça ne servirait à rien puisque, je te le répète, tu ne peux pas te servir du paramètre renvoyé par la fonction comme s'il s'agissait d'une liste de valeurs séparées par des virgules que tu taperais à la main. SQL ne voit qu'une seule valeur égale à ta pseudo liste et non pas une liste de valeurs séparées par des virgules comme tu le penses. J'espère me faire bien comprendre ce coup-ci
    Je pense que tu veux simplement éviter d'avoir à taper la liste des valeurs sur le WHERE et que tu comptes sur ta fonction pour le faire à ta place. Si c'est bien ça, je laisserais tomber la fonction et créerais simplement une nouvelle table reprenant les valeurs sur autant de lignes (enregistrements) qu'il y a de valeurs dans la liste de ton prédicat WHERE. Par exemple, j'insérerais dans cette table une ligne avec "ES", une ligne avec "SO" et une ligne avec "VA" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    CREATE TABLE MABIB.MATABLE (DOSGQDO CHAR ( 2) NOT NULL WITH DEFAULT)
    INSERT INTO MABIB.MATABLE VALUES('ES')
    INSERT INTO MABIB.MATABLE VALUES('SO')
    INSERT INTO MABIB.MATABLE VALUES('VA')
    Puis, si je veux "TOUT", je taperais directement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT a.* 
    FROM   PROD.DOSLIEF a 
    JOIN     MABIB.MATABLE b
    ON       a.dosgqdo = b.dosgqdo
    sinon, j'indiquerais directememnt la valeur sur le WHERE :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT * 
    FROM   PROD.DOSLIEF  
    WHERE dosgqdo = 'MaValeur'

    Remarque : les caractères joker n'ont rien à voir ici. Pour simplifier disons qu'un caractère joker est un pseudo caractère dont on tient compte de la position mais pas de la valeur. Il est en général représenté par un ?.
    Exemple :
    ?oue recherche toutes les valeurs telles que boue, roue, joue, noue, moue, etc.

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 42
    Points : 31
    Points
    31
    Par défaut
    RE,

    je suis d'accord avec toi je comprends ce que tu me dis
    mais alors
    cette requête
    select * from infocprod.doslief where dosgqdo in (select dosgqdo from prod.doslief group by dosgqdo )
    fonctionne
    si je fais
    select dosgqdo from prod.doslief group by dosgqdo
    cela me renvoie bien une colonne avec plusieurs ligne
    et non pas plusieurs champs séparé par des virgules.

    Ton idée de la table est bien mais seulemnt il me faut bien la fonction. cela servira dans mon interface avec les utilisateurs.
    Je veux leurs permettre de saisir '*' pour avoir toute leur donnée et si ils veulent un champs particulier ils le saisissent.
    je vais regarder si je ne peux pas faire une fonction de la suggestion que tu m'as faites.

  8. #8
    Membre expérimenté

    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 298
    Points : 1 578
    Points
    1 578
    Par défaut
    Je te propose alors de faire la fonction table (UDTF) suivante. Je voulais l'éviter car ce type de fonction est consommateur de ressources machine, je n'y suis pas favorable, mais après tout devant ton insistance, je te montre comment faire si cela t'intéresse :

    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
    drop function fgesjokltt;                                           
    create function fgesjokltt(ST VARCHAR(4))                             
     returns table ( FLD1 char(5), FLD2 decimal(5, 0), FLD3 decimal(5, 0), ... )  
     language sql                                                         
     deterministic                                                        
     disallow parallel                                                    
     no external action                                                   
     modifies sql data                                                    
     begin
                                                                    
      Declare TABLE_ALREADY_EXISTS Condition For '42710';                 
      Declare CONTINUE HANDLER For TABLE_ALREADY_EXISTS                   
      Delete From Session.Return_Tbl;                                     
                                                                          
      Declare Global Temporary Table Session.Return_Tbl (                 
       FLD1 char(5), FLD2 decimal(5, 0), FLD3 decimal(5, 0), ... );               
                                                                       
      If ST = '*' or ST = '' or ST = 'TOUT' Then                       
         Insert Into Session.Return_Tbl                                
              ( Select * From MaTable Where FLD1 In ( '10', '15', '20' )  );  
      Else                                                             
         Insert Into Session.Return_Tbl                                
              ( Select * From MaTable Where FLD1 = ST );                
      End if;                                                          
                                                                       
      Return Select * From Session.Return_Tbl;                         
                                                                       
    end
    Il faut que dans le RETURNS TABLE et dans le "Declare Global Temporary Table" tu définisses les champs de la table globale temporaire que le fonction va retourner. Dans mon exemple, j'ai défini 3 champs FLD1, 2 et 3; à toi de les modifier pour être en concordance avec ta table à renvoyer.

    Dans les 2 "Select d'insertion", modifie les requêtes pour isoler dans la table globale temporaire les lignes que tu veux provenant de ta ou tes table(s) d'origine.

    Le mot clé Session est réservé est doit être utilisé comme indiqué lors de chaque référence à la table globale temporaire.

    Une fois la fonction ajustée à tes besoins et sa compil OK, l'appeler avec la requête

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select * from table(FGESJOKLTT('*')) as ...
    pour lister les lignes 'ES', 'VA' ,'SO'

    ou bien

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select * from table(FGESJOKLTT('ES')) as ...
    pour isoler les lignes 'ES'.

    Tiens-nous au courant please.

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 42
    Points : 31
    Points
    31
    Par défaut
    Bonjour,

    Super génial
    Merci beaucoup j'y serais jamais arrivé seul

    en dernier recours hier soir (je n'avais pas encore vu ta solution) je travailllais sur ceci
    create function BIB.fgesjoklt9(ST VARCHAR(4))
    returns table (AB char(3))
    LANGUAGE SQL
    DISALLOW PARALLEL
    MODIFIES SQL DATA
    NOT FENCED

    begin

    if ST = '*' or ST = '' or ST= 'TOUT' then
    return
    select dosgqdo from prod.doslief group by dosgqdo ;
    else
    return
    select dosgqdo from prod.doslief where dosgqdo = ST group by dosgqdo ;


    END IF;
    mais effectivement cela ne pouvait pas marcher

    là je suis bluffé je ne connaissais pas
    Declare TABLE_ALREADY_EXISTS Condition For '42710';
    Declare CONTINUE HANDLER For TABLE_ALREADY_EXISTS
    Delete From Session.Return_Tbl;

    Declare Global Temporary Table Session.Return_Tbl
    je vais chercher de la doc la dessus
    Encore merci.
    Pour la consommation de ressource je vais faire attention pour ne laisser ces requêtes qu'à un nombre limité d'utilisateurs.

  10. #10
    Membre expérimenté

    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 298
    Points : 1 578
    Points
    1 578
    Par défaut
    Tu trouveras la doc complète sur les Procédures Stockées et les Fonctions dans le Redbook ci-dessous que je te recommande de télécharger et de conserver précieusement sur ton PC pour références actuelles et ultérieures.

    Stored Procedures, Triggers, and User-Defined Functions on DB2 Universal Database for iSeries

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 04/07/2007, 18h31
  2. Fonctions aléatoires pour caractères
    Par IDE dans le forum C
    Réponses: 14
    Dernier message: 13/05/2007, 15h06
  3. [Conception] Fonction pour conversion caractère
    Par GarGamel55 dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 12/08/2006, 21h03
  4. Réponses: 2
    Dernier message: 15/10/2005, 23h29
  5. Réponses: 2
    Dernier message: 04/09/2004, 10h53

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