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

PostgreSQL Discussion :

Récursivité SQL PL/SQL (Postgresql)


Sujet :

PostgreSQL

  1. #1
    Expert éminent
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Points : 9 127
    Points
    9 127
    Par défaut Récursivité SQL PL/SQL (Postgresql)
    Salut

    J'ai une table hiérarchique
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CREATE TABLE workgroup (
    wg_id INTEGER NOT NULL;
    wg_parent_id INTEGER NULL;
    wg_label VARCHAR(255);
    ...
    );
    j'ai donc dans cette table des groupes hiérarchisés
    par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    1, NULL, SUPER ADMIN
    2, 1, ADMIN A
    3, 1, ADMIN B
    4, 2, USER a
    5, 2, USER b
    6, 2, USER b
    7, 2, USER d
    8, 2, USER e
    9, 3, USER 1
    10, 3, USER 2
    11, 3, USER 3
    12, 3, USER 4
    Je cherche à trouver tous les descendants d'un group
    par exemple sur le SUPER ADMIN je récupère tout
    mais sur l'ADMIN A je veux
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    2, 1, ADMIN A
    4, 2, USER a
    5, 2, USER b
    6, 2, USER b
    7, 2, USER d
    8, 2, USER e
    Mon problème est que je ne connais pas à l'avance la profondeur de l'arbre
    la seule solution que j'ai trouvé créer une fonction récursive
    mais ça plante!!
    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
    CREATE OR REPLACE FUNCTION testQuery(INT) RETURNS SETOF workgroup AS 
    '
    DECLARE 
       _row           workgroup%ROWTYPE;
       _wg_id        ALIAS FOR $1;
     
    BEGIN
     
        SELECT INTO _row * FROM workgroup WHERE wg_id = _wg_id OR wg_parent_id = _wg_id;
        WHILE  FOUND LOOP
            RETURN NEXT _row;
            SELECT INTO _row * FROM workgroup WHERE wg_parent_id = _row.wg_id;
        END LOOP;
        RETURN;
    END
     
    ' LANGUAGE 'plpgsql';
    SELECT * FROM testQuery(1);
    le problème avec cette façon de faire c'est que je ne parcours qu'une seule branche
    j'obtiens donc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    1, NULL, SUPER ADMIN
    2, 1, ADMIN A
    4, 2, USER a
    me manque donc tous les autres fils d'ADMIN A et ADMIN B et ses fils
    j'ai donc pensé rappeler ma fonction sur chaque fils
    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
    16
    17
    18
    CREATE OR REPLACE FUNCTION testQuery2(INT) RETURNS SETOF workgroup AS 
    '
    DECLARE 
       _row           workgroup%ROWTYPE;
       _wg_id        ALIAS FOR $1;
     
    BEGIN
     
        SELECT INTO _row * FROM workgroup WHERE wg_parent_id = _wg_id ;
        WHILE  FOUND LOOP
            RETURN NEXT _row;
            SELECT INTO _row * FROM testQuery2(_row.wg_id);
        END LOOP;
        RETURN;
    END
     
    ' LANGUAGE 'plpgsql';
    SELECT * FROM testQuery2(1);
    Je perd la racine mais ça encore ce n'est pas grave mais contrairement à ce que je pensais je ne parcours pas tous les fils.

    A+JYT

  2. #2
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 937
    Points : 4 358
    Points
    4 358
    Par défaut
    Citation Envoyé par sekaijin
    Salut

    J'ai une table hiérarchique


    Je perd la racine mais ça encore ce n'est pas grave mais contrairement à ce que je pensais je ne parcours pas tous les fils.

    A+JYT

    la méthode classique pour dérécursifier une méthode est d'utiliser un "stack"…

    dans le contexte de PL/SQL, ce stack pourrait être une table temporaire
    et le résultat devant être collecter sous forme d'un ensemble on pourrait aussi l'implémenter sous forme de table temporaire…


    en "pseudo" code :
    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
     
    create temp table wg_stack (id int);
    create temp table wg_result (id int);
     
    -- la racine fait partie des résultats
    insert into wg_result(id) values(_wg_id);
     
    -- mettre dans le stack les premiers fils
    insert into wg_stack select id from workgroup where wg_parent_id = _wg_id ;
     
    -- "pop" le prochain id à traiter 
    select into current_id id from wg_stack limit 1 ;
    while found loop
        delete from wg_stack where id = current_id ;
     
        insert into wg_stack select id from workgroup where wg_parent_id = current_id ;
        insert into wg_result select id from workgroup where wg_parent_id = current_id ;
     
        select into current_id id from wg_stack limit 1 ;
    end loop ;
     
     
    -- wg_result contient tous les fils de _wg_id
    for r in select distinct id from wg_result
        return next _row ;
    end loop ;
     
    return ;

Discussions similaires

  1. SQL SERVER vers PostgreSQL
    Par mamiberkof dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 13/11/2007, 18h38
  2. Comparaison SGBD Proprio (MS SQL) et OpenSource (PostgreSQL)
    Par Franck_P dans le forum Décisions SGBD
    Réponses: 2
    Dernier message: 24/01/2007, 10h34
  3. Problème de traduction de SQL Oracle vers PostgreSQL
    Par Montaigne dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 26/04/2006, 11h15
  4. SQL server vs postgreSQL
    Par skaii dans le forum PostgreSQL
    Réponses: 6
    Dernier message: 15/02/2005, 08h05
  5. syntax sql spéciale pour postgresql ???
    Par krimson dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 05/05/2004, 15h23

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