Récursivité SQL PL/SQL (Postgresql)
Salut
J'ai une table hiérarchique
Code:
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:
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:
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:
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:
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:
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