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

PL/SQL Oracle Discussion :

Filtrage d'un arbre (tableau)


Sujet :

PL/SQL Oracle

  1. #1
    Membre régulier
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Décembre 2006
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 255
    Points : 100
    Points
    100
    Par défaut Filtrage d'un arbre (tableau)
    Bonjour,

    voilà ça fait un petit moment que j'ai écrit une fonction PL/SQL qui génère un tableau (requête hiérarchique), qui est ensuite lu par du javascript (simplement transféré dans une variable) afin de générer un arbre HTML.

    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
    40
    41
    42
    43
    44
    45
    46
    DECLARE
    	CURSOR cur IS
    	select op_id, 
    	op_descript,
    	op_id||' '||op_descript as description,
    	op_responsible,
    	op_veda_name,
    	op_begin,
    	op_end,
    	level,
    	CONNECT_BY_ISLEAF as leaf
    	from operations
    	connect by prior op_id = op_parent_op_id start with op_id = 9226;
    	levelPrec integer := 1;
    	wasLeaf boolean := false;
    	descr varchar2(500);    
    BEGIN
    	HTP.prn('[');
    	for c in cur loop
    		-- numbers of parents to close if level decrease
    		while ((levelPrec - c.level) > 0) loop
    			HTP.prn('],');
    			levelPrec := levelPrec - 1;
    			wasLeaf := false;
    		end loop;
    		-- if last item was a leaf, print a comma before the next one
    		if (wasLeaf) then
    			HTP.prn(',');
    		end if;
    		descr := translate(c.description,'''"','  ');
    		if (c.leaf = 0) then 
    			HTP.prn('["'||descr||'",0,');	
    			wasLeaf := false;
    		else
    			HTP.prn('["'||descr||'"]');
    			wasLeaf := true;
    		end if;
    		levelPrec := c.level;
    	end loop;
    	-- parents left to close
    	while (levelPrec > 1) loop
    		HTP.prn(']');
    		levelPrec := levelPrec - 1;
    	end loop;
    	HTP.p(']');
    END;
    Ca fonctionne parfaitement.

    Mais j'aimerais maintenant pouvoir filtrer l'arbre en fonction de la valeur de certain champs. J'ai naturellement essayé avec un WHERE dans la requête, mais celle-ci peut alors retourner des items de n'importe quel level (fils sans père etc...) et évidemment ça foire à la génération.

    J'ai donc essayé d'ajouter un if comme ceci :

    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    DECLARE
    	CURSOR cur IS
    	select op_id, 
    	op_descript,
    	op_id||' '||op_descript as description,
    	op_responsible,
    	op_veda_name,
    	op_begin,
    	op_end,
    	level,
    	CONNECT_BY_ISLEAF as leaf
    	from operations
    	connect by prior op_id = op_parent_op_id start with op_id = 9226;
    	levelPrec integer := 1;
    	wasLeaf boolean := false;
    	descr varchar2(500);    
    BEGIN
    	HTP.prn('[');
    	for c in cur loop
    		-- numbers of parents to close if level decrease
    		while ((levelPrec - c.level) > 0) loop
    			HTP.prn('],');
    			levelPrec := levelPrec - 1;
    			wasLeaf := false;
    		end loop;
    		-- if last item was a leaf, print a comma before the next one
    		if (wasLeaf) then
    			HTP.prn(',');
    		end if;
    		descr := translate(c.description,'''"','  ');
    		--if item have to be displayed
    		if (c.op_id like '%'||:P2_FILTRE_ID||'%' and upper(c.op_descript) like '%'||upper(:P2_FILTRE_DESCRIPTION)||'%' and upper(c.op_responsible) like '%'||upper(:P2_FILTRE_RESPONSABLE)||'%' and upper(c.op_veda_name) like upper(:P2_FILTRE_VEDA_NAME) and (c.op_begin > nvl(:P2_FILTRE_DATE_DEBUT,SYSDATE- numtoyminterval(60,'YEAR')) or c.op_begin is null) and (c.op_end < nvl(:P2_FILTRE_DATE_FIN,SYSDATE+1) or c.op_end is null)) then
    			if (c.leaf = 0) then 
    				HTP.prn('["'||descr||' t",0,');	
    				wasLeaf := false;
    			else
    				HTP.prn('["'||descr||' t"]');
    				wasLeaf := true;
    			end if;
    		else
    			if (c.leaf = 0) then 
    				HTP.prn('["'||descr||' f",0,');	
    				wasLeaf := false;
    			else
    				HTP.prn('["'||descr||' f"]');
    				wasLeaf := true;
    			end if;
    		end if;
    		levelPrec := c.level;
    	end loop;
    	-- parents left to close
    	while (levelPrec > 1) loop
    		HTP.prn(']');
    		levelPrec := levelPrec - 1;
    	end loop;
    	HTP.p(']');
    END;
    afin de génèrer le tableau complet mais en ajoutant à la fin de chaque item ' f' ou ' t' pour savoir si l'item doit être afficher ou non, ensuite je comptais enlever les items finissant par ' f' via javascript, mais ca fait 2 jours que je suis sur la fonction javascript et ça ne fonctionne pas. De plus il serait plus performant de générer directement le bon arbre avec le programme PL/SQL.

    Pour l'instant ça génère un tableau de la sorte (si je décide d'afficher que les élément dont l'id contient un 1) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    [["9226 mesure ECOOL f",0,
     ["9227 mesure ECOOL f",0,
      ["9240 TD62 - Tracés au sol f"],
      ["10872 mesure ECOOL t",0,
       ["10873 mesure ECOOL t"]
      ],
     ],
     ["9228 TD68 f",0,
      ["9241 TD68 - Tracés au sol t"],
      ["10905 mesure ECOOL t",0,
       ["10906 mesure ECOOL t"]
      ]
     ]
    ]]
    Et il faudrait que ça génère directement ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    [
     ["10872 mesure ECOOL",0,
      ["10873 mesure ECOOL"]
     ],
     ["9241 TD68 - Tracés au sol"],
     ["10905 mesure ECOOL",0,
      ["10906 mesure ECOOL"]
     ]
    ]
    Dans la vraie vie ma table Opérations possède plus de 12 000 enregistrments donc l'arbre et bien plus gros.

    J'espère avoir été clair

    Merci pour votre aide, je suis dessus depuis la semaine dernière, et j'ai le cerveau qui s'enmèle, je ne sais plus quoi tenter :/

  2. #2
    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
    Houlala.. c'est compliqué ..
    Bon, j'ai peut être une idée :
    Est ce que tu peux utiliser le chemin (SYS_CONNECT_BY_PATH) pour avoir la liste des id ayant conduit à la ligne en cours ?
    Ensuite une condition sur l'existence d'un 1 dedans
    Ca donnerait (schématiquement)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT *
    FROM 
    ( SELECT SYS_CONNECT_BY_PATH(op_id,'-') as chemin, op_id, op_descript
    FROM .. CONECT BY ..)
    WHERE instr(chemin, '1') > 0
    Peut être que ça peut t'aider comme base pour ce que tu veux faire.
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  3. #3
    Membre régulier
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Décembre 2006
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 255
    Points : 100
    Points
    100
    Par défaut
    Merci pour la réponse, à vrai dire je ne pensais même pas en avoir une
    Car c'est vrai que c'est compliqué pour quelqu'un qui n'a pas suivi depuis le début de se mettre dans le bain.

    J'avais totalement oublié SYS_CONNECT_BY_PATH, je peux peut-être faire quelquechose avec en effet. Mais le filtrage peut être fait sur tous les champs de la table (op_id, op_descript, op_responsible, op_veda_name, op_begin, op_end) et pas seulement sur l'id. Il me faudra donc un SYS_CONNECT_BY_PATH pour chaque champs.
    Je vais étudier ça

    Perso je pensais plutôt modifier le 2ème programme que j'ai indiqué, notamment le else (ligne 40, si l'item ne doit pas être afficher), en décrémentant le level de 1 juste le temps qu'il faut (jusqu'à ce qu'on repasse à un noeud du même level que le noeud qui n'a pas été affiché).

    Car en gros le fonctionnement c'est si un noeud n'est pas affiché, ses enfants deviennent les enfants du père du noeud qui n'est pas affiché. Ca revient à décrémenter le level de 1 pour tous les enfants (et les sous-enfants etc...) je pense. Je ne sais pas si je suis clair

  4. #4
    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
    Si si, ta dernière phrase est super claire.
    Par contre, comment réaliser une modification d'arbre en supprimant juste des noeuds, et en requête, je crains de ne pouvoir t'aider.

    Moi ce que je ferais c'est insérer le résultat de ta requête d'arbre dans une collection, et la retraiter ensuite.
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  5. #5
    Membre régulier
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Décembre 2006
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 255
    Points : 100
    Points
    100
    Par défaut
    C'est ce que je fait pour l'instant, je place le resultat complet de la requete dans un tableau (en ajoutant ' f' pour false ou ' t' pour true au nom de l'item pour savoir si je devrai le retirer ou non).

    Puis j'ai une fonction javascript qui retire tous les éléments finissants par ' f' (ainsi que l'élément 0 associé), attention ça pique les yeux :

    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
     
    function recur(arr){
    	for(var k=0;k<arr.length;k++){
    		if (typeof arr[k] == "string") {
    			if (/ f$/.test(arr[k])) {
    				arr.splice(k,1);
    				if (arr[k] == 0) 
    					arr.splice(k--,1);
    			}
    		}
    		else {
    			new recur(arr[k]);
    			if (arr[k].length == 0)
    				arr.splice(k,1);
    		}
    	}
    }
    Le problème là c'est qu'après traitement il me reste des tableaux vides, ou du moins inutiles.

    Par exemple j'obtiens ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    '[[[["10872 mesure ECOOL t",0,["10873 mesure ECOOL t"]]],[["9241 TD68 - Tracés au sol t"],["10905 mesure ECOOL t",0,["10906 mesure ECOOL t"]]]]]'
    au lieu de ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    '[["10872 mesure ECOOL t",0,["10873 mesure ECOOL t"]],["9241 TD68 - Traces au sol t"],["10905 mesure ECOOL t",0,["10906 mesure ECOOL t"]]]'
    Donc la fonction qui construit l'arbre HTML n'aime pas les tableaux en trop. Et je ne vois pas du tout comment supprimer les tableaux redondants...

  6. #6
    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
    Bon, tu vas m'obliger à le coder
    Je te tiens au courant d'ici ce soir.
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  7. #7
    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
    Voici ce que j'ai réussi à faire (mais je n'ai pas de jeu de donnée suffisant pour tester tous les cas)

    Mon cas : Un regroupement d'article, lui même pouvant être regroupé.

    Je n'ai testé qu'un seul cas de restriction de noeud/feuille : Si un article contient le code 7
    Cas normal
    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
     
    SELECT ROWNUM norec, LEVEL, article,
           SYS_CONNECT_BY_PATH(article,'+') AS chemin
           FROM CONCEPTLIG
          CONNECT BY  article_concept = PRIOR article 
          START WITH article = '9911909000'
     
    NOREC	LEVEL	ARTICLE	CHEMIN
    1	1	9911909000	+9911909000
    2	2	9911910106	+9911909000+9911910106
    3	3	9911900112	+9911909000+9911910106+9911900112
    4	3	9911900113	+9911909000+9911910106+9911900113
    5	2	9911910107	+9911909000+9911910107
    6	3	9911900114	+9911909000+9911910107+9911900114
    7	3	9911900115	+9911909000+9911910107+9911900115
    8	2	9911910112	+9911909000+9911910112
    9	2	9911910113	+9911909000+9911910113
    10	2	9911910118	+9911909000+9911910118
    11	2	9911910119	+9911909000+9911910119
    12	2	9911910126	+9911909000+9911910126
    13	2	9911910127	+9911909000+9911910127
    Maintenant avec la restriction : Concernant le chemin, je compte le nombre de noeud ne présentant pas de 7 (et je limite la requête pour enlever les enreg contenant 7)
    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
     
    SELECT ROWNUM norec, LEVEL, article,
           SYS_CONNECT_BY_PATH(article,'+') AS chemin,
    SYS_CONNECT_BY_PATH(DECODE(INSTR(article,'7'),0, '1','0'),'+') as cod_nb_lev,
           EXECUTE_REQUETE('select 0 '||SYS_CONNECT_BY_PATH(DECODE(INSTR(article,'7'),0, '1','0'),'+')||' from dual') new_level
          FROM CONCEPTLIG
          WHERE INSTR(article,'7') = 0
          CONNECT BY  article_concept = PRIOR article 
          START WITH article = '9911909000'
     
    NOREC	LEVEL	ARTICLE	CHEMIN	COD_NB_LEV	NEW_LEV
    1	1	9911909000	+9911909000	+1	1
    2	2	9911910106	+9911909000+9911910106	+1+1	2
    3	3	9911900112	+9911909000+9911910106+9911900112	+1+1+1	3
    4	3	9911900113	+9911909000+9911910106+9911900113	+1+1+1	3
    5	3	9911900114	+9911909000+9911910107+9911900114	+1+0+1	2
    6	3	9911900115	+9911909000+9911910107+9911900115	+1+0+1	2
    7	2	9911910112	+9911909000+9911910112	+1+1	2
    8	2	9911910113	+9911909000+9911910113	+1+1	2
    9	2	9911910118	+9911909000+9911910118	+1+1	2
    10	2	9911910119	+9911909000+9911910119	+1+1	2
    11	2	9911910126	+9911909000+9911910126	+1+1	2
    Avec la fonction EXECUTE_REQUETE qui fait juste un retour d'une requete dynamique
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    FUNCTION EXECUTE_REQUETE(p_requete IN VARCHAR2) RETURN NUMBER
    IS 
    BEGIN
    EXECUTE IMMEDIATE p_requete INTO v_retour
    RETURN v_retour;
    END;
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  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
    Y'a plus simple pour le nouveau level
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    length(REPLACE(SYS_CONNECT_BY_PATH(DECODE(INSTR(article,'7'),0, '1',''),' '),' ')) AS new_level
    et plus besoin de function execute_requete.
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  9. #9
    Membre régulier
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Décembre 2006
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 255
    Points : 100
    Points
    100
    Par défaut
    Oulla En aucun cas je voulais t'obliger à le coder

    Je regarde ça à tête reposé et je te redis dans la soirée.

    Merci !

  10. #10
    Membre régulier
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Décembre 2006
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 255
    Points : 100
    Points
    100
    Par défaut
    OK donc si je comprend bien le vrai level de mon arbre sera NEW_LEVEL - LEVEL.

    J'ai adapté le code à mes besoins, ici je sélectionne toutes les opérations ayant 873 dans l'id.

    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
    40
    41
    42
    43
    44
    45
    46
    47
    DECLARE
    	CURSOR cur IS
    	select op_id,
    	op_id||' '||op_descript as description,
    	level,
    	CONNECT_BY_ISLEAF as leaf,
    	SYS_CONNECT_BY_PATH(op_id,'+') AS chemin,
    	SYS_CONNECT_BY_PATH(DECODE(INSTR(op_id,'873'),0, '1','0'),'+') AS cod_nb_lev,
    	length(REPLACE(SYS_CONNECT_BY_PATH(DECODE(INSTR(op_id,'873'),0, '1',''),' '),' ')) AS new_level
    	from operations
    	WHERE op_id like '%873%'
    	connect by prior op_id = op_parent_op_id start with op_id = 15000;
    	levelPrec integer := 1;
    	wasLeaf boolean := false;
    	descr varchar2(500);
    	vraiLevel integer;    
    BEGIN
    	HTP.prn('[');
    	for c in cur loop
    		vraiLevel := c.level - c.new_level;
    		-- numbers of parents to close if level decrease
    		while ((levelPrec - vraiLevel) > 0) loop
    			HTP.prn('],');
    			levelPrec := levelPrec - 1;
    			wasLeaf := false;
    		end loop;
    		-- if last item was a leaf, print a comma before the next one
    		if (wasLeaf) then
    			HTP.prn(',');
    		end if;
    		descr := translate(c.description,'''"','  '); 
    		if (c.leaf = 0) then 
    			HTP.prn('["'||descr||' t",0,');	
    			wasLeaf := false;
    		else
    			HTP.prn('["'||descr||' t"]');
    			wasLeaf := true;
    		end if;
    		levelPrec := vraiLevel;
    	end loop;
    	-- parents left to close
    	while (levelPrec > 1) loop
    		HTP.prn(']');
    		levelPrec := levelPrec - 1;
    	end loop;
    	HTP.p(']');
    END;
    La requête seule me retourne ça (j'ai juste enlever la description pour pas faire trop long) :

    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
    OP_ID	LEVEL	LEAF	CHEMIN						COD_NB_LEV		NEW_LEVEL
    8873	6	1	+15000+8376+8681+10510+8377+8873		+1+1+1+1+1+0		5
    10873	6	1	+15000+8376+9226+9227+10872+10873		+1+1+1+1+1+0		5
    1873	5	1	+15000+8454+8455+8599+1873			+1+1+1+1+0		4
    8736	4	0	+15000+8454+8455+8736				+1+1+1+0		3
    8735	4	0	+15000+8454+8456+8735				+1+1+1+0		3
    8730	4	0	+15000+8454+8457+8730				+1+1+1+0		3
    2873	5	1	+15000+8454+8458+8625+2873			+1+1+1+1+0		4
    8733	5	0	+15000+8454+8460+8463+8733			+1+1+1+1+0		4
    8734	5	0	+15000+8454+8460+8465+8734			+1+1+1+1+0		4
    8732	5	0	+15000+8454+8460+8640+8732			+1+1+1+1+0		4
    8731	4	0	+15000+8454+8596+8731				+1+1+1+0		3
    4873	5	1	+15000+8462+8467+8693+4873			+1+1+1+1+0		4
    7873	6	1	+15000+8585+8407+8401+8356+7873			+1+1+1+1+1+0		5
    6873	6	1	+15000+8585+8407+8401+8357+6873			+1+1+1+1+1+0		5
    3873	6	1	+15000+8585+8407+8797+8658+3873			+1+1+1+1+1+0		5
    8738	5	0	+15000+8585+8407+8808+8738			+1+1+1+1+0		4
    5873	6	1	+15000+8585+8407+8809+8746+5873			+1+1+1+1+1+0		5
    873	6	1	+15000+8585+8407+8812+8814+873			+1+1+1+1+1+0		5
    8739	5	0	+15000+8585+8592+8409+8739			+1+1+1+1+0		4
    9873	8	1	+15000+8585+8592+8588+10325+9283+9291+9873	+1+1+1+1+1+1+1+0	7
    8737	4	0	+15000+8585+8729+8737				+1+1+1+0		3
    Mais le tableau généré est faux :

    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
    [
    	["8873 LHC - Réseau - Mesures de contrôle au mékomètre dans le secteur 8-1 t"],
    	["10873 mesure ECOOL t"],["1873 Alignement de PRURL51 du 21-OCT-1987 t"],
    	["8736 PSR- Alignements réalisés en 1999 t",0,
    		["8735 PSB- Alignements réalisés en 1999 t",0,
    			["8730 AD-DE- Alignements réalisés en 1999 t",0,
    				["2873 Alignement de WLQNF3311 du 05-APR-1989 t"],
    				["8733 FT16- Alignements réalisés en 1999 t",0,
    					["8734 LTB-LBE- Alignements réalisés en 1999 t",0,
    						["8732 BT- Alignements réalisés en 1999 t",0,
    							["8731 CIACOL- Alignements réalisés en 1999 t",0,
    								["4873 Alignement de POUTRE3 du 29-APR-1996 t"],
    								["7873 Alignement de MBA62430 du 03-APR-2001 t"],
    								["6873 Alignement de BPV32109 du 25-JAN-2001 t"],
    								["3873 Alignement de QF33210 du 17-FEB-1992 t"],
    								["8738 SPS- Alignements réalisés en 1999 t",0,
    									["5873 Alignement de QF30610 du 07-JAN-2000 t"],
    									["873 Alignement de MBB61270 du 29-JAN-1987 t"],
    									["8739 TT20-TT22-TT23-TT24-TT25- Alignements réalisés en 1999 t",0,
    										["9873 mesure ECOOL t"],
    										["8737 SDF- Alignements réalisés en 1999 t",0,
    											]
    On dirait qu'il ne passe jamais dans la boucle while permettant de fermer si le level descend.

    Je doit partir du boulo là, je réfléchierai chez moi ce soir si j'ai le temps, et je testerai des choses demain. En attendant si tu as une idée n'hésite pas.

    Merci encore, je n'aurais jamais pensé à ça, chapeau ! On ne doit pas être loin de la solution.


  11. #11
    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
    Euh, non le nouveau level doit être le new_level

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    OP_ID	LEVEL	LEAF	CHEMIN						COD_NB_LEV		NEW_LEVEL
    8873	6	1	+15000+8376+8681+10510+8377+8873		+1+1+1+1+1+0		5
    Je ne comprends pas ta première ligne.. normalement tu aurais du avoir la ligne 15000.... Ah si, j'ai trouvé..
    Oups, mon code est fait de façon à ne pas prendre les '7', du coup le decode pour le new_level, si y'a pas de 7, je mets 1..
    Toi il faut que tu inverses !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SYS_CONNECT_BY_PATH(DECODE(INSTR(op_id,'873'),0, '0','1'),'+') AS cod_nb_lev,
    length(REPLACE(SYS_CONNECT_BY_PATH(DECODE(INSTR(op_id,'873'),0, '','1'),' '),' ')) AS new_level
    Et le new_level devrait commencer à 1 pour la première ligne !
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  12. #12
    Membre régulier
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Décembre 2006
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 255
    Points : 100
    Points
    100
    Par défaut
    Hmm théoriquement si j'inverse, et que je prend le NEW_LEVEL au lieu de LEVEL-NEW_LEVEL, ça devrait revenir au même

    Je test ça demain à la première heure

  13. #13
    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
    Citation Envoyé par Yann39 Voir le message
    Hmm théoriquement si j'inverse, et que je prend le NEW_LEVEL au lieu de LEVEL-NEW_LEVEL, ça devrait revenir au même
    Tu as raison..
    Le problème ne vient pas de là, mais de ton test sur leaf.
    Tous les new_level de ton exemple sont à 1, donc tu ne devrais pas créer de noeud.
    Il faudrait modifier ton test en mettant le ,0,' lorsque tu traites la ligne suivante et qu'elle a un new_level > à la ligne précédente.
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  14. #14
    Membre régulier
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Décembre 2006
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 255
    Points : 100
    Points
    100
    Par défaut
    Exact

    J'ai donc modifié comme ceci et ça fonctionne !

    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
    40
    41
    42
    43
    44
    45
    DECLARE
    	CURSOR cur IS
    	select op_id,
    	op_id||' '||op_descript as description,
    	level,
    	CONNECT_BY_ISLEAF as leaf,
    	SYS_CONNECT_BY_PATH(op_id,'+') AS chemin,
    	SYS_CONNECT_BY_PATH(DECODE(INSTR(op_id,'73'),0, '0','1'),'+') AS cod_nb_lev,
    	length(REPLACE(SYS_CONNECT_BY_PATH(DECODE(INSTR(op_id,'73'),0, '','1'),' '),' ')) AS new_level
    	from operations
    	WHERE op_id like '%73%'
    	connect by prior op_id = op_parent_op_id start with op_id = 15000;
    	levelPrec integer := 1;
    	wasLeaf boolean := false;
    	descr varchar2(500); 
    BEGIN
    	HTP.prn('[');
    	for c in cur loop 
    		-- numbers of parents to close if level decrease
    		while ((levelPrec - c.new_level) > 0) loop
    			HTP.prn('],');
    			levelPrec := levelPrec - 1;
    			wasLeaf := false;
    		end loop;
    		-- if last item was a leaf, print a comma before the next one
    		if (wasLeaf) then
    			HTP.prn(',');
    		end if;    
    		descr := translate(c.description,'''"','  '); 
    		if (c.new_level > levelPrec) then 
    			HTP.prn('["'||descr||' t",0,');	
    			wasLeaf := false;
    		else     
    			HTP.prn('["'||descr||' t"]');
    			wasLeaf := true;
    		end if;   
    		levelPrec := c.new_level;
    	end loop;
    	-- parents left to close
    	while (levelPrec > 1) loop
    		HTP.prn(']');
    		levelPrec := levelPrec - 1;
    	end loop;
    	HTP.p(']');
    END;
    Par contre je m'apperçoi que lorsque tous les levels sont à 1 l'arbre met très longtemps à s'afficher.
    Et je viens de penser que l'idéal serait d'afficher l'arbre exactement sous la forme de la colonne "Chemin", c'est à dire avec les noeuds permettant d'accéder à chaque item :

    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
    OP_ID	LEVEL	LEAF	CHEMIN						COD_NB_LEV		NEW_LEVEL
    8873	6	1	+15000+8376+8681+10510+8377+8873		+1+1+1+1+1+0		5
    10873	6	1	+15000+8376+9226+9227+10872+10873		+1+1+1+1+1+0		5
    1873	5	1	+15000+8454+8455+8599+1873			+1+1+1+1+0		4
    8736	4	0	+15000+8454+8455+8736				+1+1+1+0		3
    8735	4	0	+15000+8454+8456+8735				+1+1+1+0		3
    8730	4	0	+15000+8454+8457+8730				+1+1+1+0		3
    2873	5	1	+15000+8454+8458+8625+2873			+1+1+1+1+0		4
    8733	5	0	+15000+8454+8460+8463+8733			+1+1+1+1+0		4
    8734	5	0	+15000+8454+8460+8465+8734			+1+1+1+1+0		4
    8732	5	0	+15000+8454+8460+8640+8732			+1+1+1+1+0		4
    8731	4	0	+15000+8454+8596+8731				+1+1+1+0		3
    4873	5	1	+15000+8462+8467+8693+4873			+1+1+1+1+0		4
    7873	6	1	+15000+8585+8407+8401+8356+7873			+1+1+1+1+1+0		5
    6873	6	1	+15000+8585+8407+8401+8357+6873			+1+1+1+1+1+0		5
    3873	6	1	+15000+8585+8407+8797+8658+3873			+1+1+1+1+1+0		5
    8738	5	0	+15000+8585+8407+8808+8738			+1+1+1+1+0		4
    5873	6	1	+15000+8585+8407+8809+8746+5873			+1+1+1+1+1+0		5
    873	6	1	+15000+8585+8407+8812+8814+873			+1+1+1+1+1+0		5
    8739	5	0	+15000+8585+8592+8409+8739			+1+1+1+1+0		4
    9873	8	1	+15000+8585+8592+8588+10325+9283+9291+9873	+1+1+1+1+1+1+1+0	7
    8737	4	0	+15000+8585+8729+8737				+1+1+1+0		3
    Je vais réfléchir un peu, en attendant si tu as une idée ! (oui oui je sais je profite de tes compétences :p).

    Merci !


  15. #15
    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
    Si j'ai bien compris, tu veux garder les noeuds parents s'il existe un enregistrement fils contenant ton critère ?
    Exemple
    Au lieu de n'avoir que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    8873	6	1	+15000+8376+8681+10510+8377+8873		+1+1+1+1+1+0		5
    Il faut aussi garder les noeuds : 15000 8376 8681 10510 et 8377 ?
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  16. #16
    Membre régulier
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Décembre 2006
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 255
    Points : 100
    Points
    100
    Par défaut
    Oui c'est ça.

    Je suis en train de tester quelquechose là mais je crois que je me suis embarquer dans un truc infaisable

  17. #17
    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
    Lol, oui ça devient super compliqué..
    Alors peut être en faisant comme ça :
    Créer la requête d'arbre complet (avec le LEAF), le rownum pour garder l'ordre, et le chemin.
    Ensuite restreindre cette requête/vue en ne gardant que les LEAF = 1 contenant ton critère 873, et en gardant les noeuds (leaf=0) pour lesquels il existe un LEAF=1 contenant ton critère
    Tu peux facilement retrouver ces noeuds grâce au chemin : Le chemin du noeud est le début du chemin du leaf...

    C'est bon ou tu veux un exemple de code ?
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  18. #18
    Membre régulier
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Décembre 2006
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 255
    Points : 100
    Points
    100
    Par défaut
    Je ne vais pas abuser de ta gentillesse

    Je vais essayer de me débrouiller. Je te tient au courant.

    Sinon je peux peut-être aussi utiliser CONNECT_BY_ROOT pour retrouver le parent d'une feuille.

  19. #19
    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
    Pas de problème. Si je code, c'est pour le plaisir (ou pour le challenge)
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  20. #20
    Membre régulier
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Décembre 2006
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 255
    Points : 100
    Points
    100
    Par défaut
    Désolé mais je ne m'en sort pas

    Je n'arrive pas à chercher dans chemin si l'op_id y apparait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    select op_id,
    	op_id||' '||op_descript as description,
    	level, rownum,
    	CONNECT_BY_ISLEAF as leaf,
    	SYS_CONNECT_BY_PATH(op_id,'+') AS chemin
    	from operations
    	where (CONNECT_BY_ISLEAF = 1 AND op_id like '%73%') OR (CONNECT_BY_ISLEAF = 0 AND op_id IN chemin)
    	connect by prior op_id = op_parent_op_id start with op_id = 15000;
    Je sais bien que le "AND op_id IN chemin" ne fonctionne pas, il faudrait que je fasse un INSTR pour savoir si l'id_op apparait dedant. Mais comment accéder à 'chemin' dans la requête ?

    J'ai fait cette requête qui permet ici de savoir si l'operation 8681 apparait dans le chemin de l'opération 8873 (en l'occurence oui) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select DECODE(INSTR(SYS_CONNECT_BY_PATH(o2.op_id,'+'),8681),0,0,1) FROM operations o2 where o2.op_id = 8873 connect by prior o2.op_id = o2.op_parent_op_id start with o2.op_id = 15000
    J'essai d'intégrer cette sous-requête.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [Toutes versions] Filtrage automatique d'un tableau
    Par kyasteph dans le forum Excel
    Réponses: 3
    Dernier message: 18/10/2013, 19h03
  2. [XL-2007] Filtrage multiple d'un tableau excel avec macro
    Par robby98800 dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 29/05/2012, 09h39
  3. Filtrage d'un Tableau et Variables
    Par TD_RTM dans le forum Mode d'emploi & aide aux nouveaux
    Réponses: 1
    Dernier message: 22/08/2006, 13h54
  4. Un arbre dans un tableau
    Par Oberown dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 01/08/2006, 10h12
  5. XSL pour visualiser arbre XML sous forme de tableau en HTML
    Par mattmat dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 28/03/2003, 10h55

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