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

Langage SQL Discussion :

Fonction avec nombre variable de paramètres et utilisation de ceux-ci


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2007
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2007
    Messages : 17
    Points : 11
    Points
    11
    Par défaut Fonction avec nombre variable de paramètres et utilisation de ceux-ci
    Bonjour à tous,

    Voici mon problème :
    Je dois créer une fonction qui prend en paramètre un nombre variable d'identifiants (numériques).
    Cette même fonction doit vérifier si ces identifiants existent dans une table et afficher les données correspondantes.

    Moyennant une astuce, j'ai réussi à faire ce que je voulais. Mais ce n'est pas très efficient et j'aimerais une meilleure façon de le réaliser.

    Voici donc ce à quoi je suis arrivé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    CREATE OR REPLACE FUNCTION fct(listeIDs text)
      RETURNS SETOF record AS
    $$
    SELECT DISTINCT annee, id
    FROM myTable
    WHERE 
    	$1 LIKE '%,' || CAST(id AS TEXT) || ',%'
    GROUP BY annee, id
    $$
      LANGUAGE sql;
    La fonction reçoit un tableau d'identifiant sous forme de texte et va rechercher dans la table "myTable" les champs "annee" et "id" lorsqu'on retrouve id dans le texte entré en paramètre (entre virgules en fait, car il s'agit d'un tableau).

    Un petit exemple d'appel à cette fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT * FROM fct('[,4504,6229,5,6,]') AS (Annee numeric, Id numeric);
    Juste pour info, mais pas nécessaire :
    j'ai simplement ajouté des virgules autour des premiers et derniers identifiants afin que si l'on cherche '2', il ne soit pas trouvé dans '6229'.

    Si vous avez une meilleure façon de réaliser cela, je suis preneur.
    Merci d'avance pour votre aide et vos conseils...

  2. #2
    Membre expérimenté
    Homme Profil pro
    Ingenieur de recherche - Ecologue
    Inscrit en
    Juin 2003
    Messages
    1 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingenieur de recherche - Ecologue

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 146
    Points : 1 412
    Points
    1 412
    Par défaut
    bonjour,

    je pense que ceci peut t'aider. J'ai trouve cela sur un forum (mais je ne sais plus ou et par qui Aussi je m'excuse d'avance auprès du créateur).

    Cela fonctionne sous FIREBIRD, donc à adapter selon ton SGBD

    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
     
    CREATE OR ALTER PROCEDURE Tokenize (
        Entree        VARCHAR(1024),
        Token         CHAR(1),
        Vide_Possible SMALLINT)
    RETURNS (
        Result VARCHAR(255))
    AS
      DECLARE VARIABLE Newpos INTEGER;
      DECLARE VARIABLE Oldpos INTEGER;
    BEGIN --Revoie les lignes d'une chaine de carateres separes par un token
        if (vide_possible not between 0 and 1) then
           vide_possible = 1;
        Oldpos = 1;
        Newpos = 1;
        WHILE (1 = 1) DO
        BEGIN
            Newpos = POSITION(Token, Entree, Oldpos);
            IF (Newpos > 0) THEN
            BEGIN
                Result = Trim(SUBSTRING(Entree FROM Oldpos FOR Newpos - Oldpos));
                if (not ((result = '') and (vide_possible = 0))) then
                   SUSPEND;
                Oldpos = Newpos + 1;
            END
            ELSE
            IF (Oldpos - 1 < CHAR_LENGTH(Entree)) THEN
            BEGIN
                if (not ((result = '') and (vide_possible = 0))) then
                   Result = Trim(SUBSTRING(Entree FROM Oldpos));
                SUSPEND;
                BREAK;
            END
            ELSE
            BEGIN
                BREAK;
            END
        END
    END
    Merci d'ajouter un sur les tags qui vous ont aidé

  3. #3
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    D'après la déclaration de fonction, le SGBD est PostgreSQL. Depuis la version 8.4 les nombres variables d'arguments sont supportés par les fonctions.

    Si ID est de type numeric, la déclration pourrait ressembler à:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CREATE OR REPLACE FUNCTION fct(variadic numeric[]) RETURNS SETOF record 
    AS $$
    SELECT annee, id FROM myTable WHERE id =ANY($1)
      GROUP BY annee, id
    $$  LANGUAGE sql;
    La syntaxe de l'appel serait du style:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM fct(4504,6229,5,6) AS (Annee numeric, Id numeric);
    Si c'est une version de postgres 8.3 ou inférieur, il faut enlever variadic de la déclaration de fonction et l'appeler comme ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM fct(array[4504,6229,5,6]) AS (Annee numeric, Id numeric);

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2007
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2007
    Messages : 17
    Points : 11
    Points
    11
    Par défaut
    Déjà, merci pour vos réponses.

    J'ai regardé en vitesse l'éventuelle solution de dehorter olivier, qui me semble légèrement plus compliquée. Je précise, pour les futurs lecteurs de ce post, que je ne l'ai pas essayée

    Pour estofilo, en effet, j'utilise PostgreSQL. L'idée de base était de créer des fonctions qui aurait permis de passer d'un SGBD à l'autre en cas de migration. Mais bon, comme on le sait, ceux-ci ne s'entendent pas toujours sur les normes et donc c'est parfois bien difficile !

    J'avais pensé à utiliser "variadic", mais cela me limitait dans le nombre de paramètres (100 maximum) et comme je ne suis pas maître de ce nombre, ca ne me convenait pas tellement...
    Par contre, j'ai essayé le même fonctionnement en utilisant "array" et là, pas de limitation... ! Du coup, cette solution me convient beaucoup mieux !

    Alors, une dernière petite question, bien que le sujet soit résolu : est-ce qu'utiliser array dans ce cas-ci est deprecated depuis la version 8.4 ou est-ce que variadic est une alternative ?

    Encore merci !

  5. #5
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    Alors, une dernière petite question, bien que le sujet soit résolu : est-ce qu'utiliser array dans ce cas-ci est deprecated depuis la version 8.4 ou est-ce que variadic est une alternative ?
    A mon sens, il n'y a aucune inquiétude à avoir sur la pérennité d'aucune des 2 formes.

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2007
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2007
    Messages : 17
    Points : 11
    Points
    11
    Par défaut
    Merci !

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

Discussions similaires

  1. Macro-fonction avec nombre de paramètres non fixé
    Par miasseu dans le forum Macro
    Réponses: 2
    Dernier message: 31/08/2012, 16h36
  2. AS3 fonction nombre variable de paramètres
    Par Goldocrack dans le forum ActionScript 3
    Réponses: 5
    Dernier message: 20/08/2011, 00h54
  3. Réponses: 0
    Dernier message: 18/03/2009, 18h00
  4. Réponses: 9
    Dernier message: 15/05/2007, 12h41
  5. Réponses: 9
    Dernier message: 24/05/2005, 16h34

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