|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | ||
|
Futur Membre du Club
![]() Inscription : juin 2007 Messages : 69 ![]() |
Bonjour à tous,
Je viens vers vous car je suis entrain de travaillé sur la récursivité sur une base SQL Server. Et je dois adapter des requêtes oracle pour cette base de données. Pour la grande majorité j'y suis arrivé sans souci seulement je me retrouve face à une requête oracle utilisant la récursivité (Start with ... connect by...). Voici la requête en question qui fonctionne bien sur Oracle. Code :
N'arrivant pas à l'adapter malgré mes recherche et le cours se sqlpro sur le forum, je me tourne vers vous. Merci d'avance Ghosty |
||
|
|
00
|
|
|
#2 |
![]() ![]() ![]() Nicolas SouquetAdministrateur de base de données Inscription : janvier 2005 Messages : 4 669 ![]() |
Bonjour,
Je pense ne pas être loin de la solution mais l'expression de la récursivité sous Oracle est un peu cryptique pour moi. Pouvez-vous m'indiquer : - quelle colonne de l'expression de table commune matable constitue le parent - quelle colonne de l'expression de table commune matable constitue l'enfant - quelle est la valeur du parent ou de l'enfant qui est la racine de la hiérarchie ? - quelle est la valeur du parent ou de l'enfant qui est la feuille de la hiérarchie ? @++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes. Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012 |
|
00
|
|
|
#3 |
|
Futur Membre du Club
![]() Inscription : juin 2007 Messages : 69 ![]() |
Bonjour,
alors en fait c'est justement la le soucis, c'est que je n'est pas de lien parent ou enfant. C'est pour cela que je fais un union all qui inverse les tables, cela me permet de couvrir ainsi tout le champ d'action du réseau de table. Le but étant de trouver le plus court chemin entre deux tables et de concaténer la partie sql afin de me fournir les relation entre les table. Par contre je ne voit pas ce que tu veux dire par racine et feuille. Pour l'exemple de la requête le résultat escompter est le suivant entre SVFAV et SGART : Code :
sgart.numsgart = svlcv.artsvlcv AND svlcv.nuisvlcv = svcdv.nuisvcdv AND svfav.numsvfav = svcdv.favsvcdv AND svfav.etssvfav = svcdv.etssvcdv Code :
gtets.numgtets = svcdv.etssvcdv AND svlcv.nuisvlcv = svcdv.nuisvcdv |
|
|
00
|
|
|
#4 | ||
|
Membre Expert
![]() ![]() Inscription : janvier 2010 Messages : 1 084 ![]() |
Bonjour
il y a surement plus optimisé, mais avec cette requête, on ne doit pas être loin du but: Code SQL :
|
||
|
|
00
|
|
|
#5 | |
|
Futur Membre du Club
![]() Inscription : juin 2007 Messages : 69 ![]() |
WooW !!
Je viens de faire quelques test ça a l'air de rouler...!! Je comprend pas tout ce que tu as fait, mais je te remercie. Je crois pas que j'aurais pu arriver à ça tout seul. edit : Que veut tu dire par : Citation:
Sinon quand tu dis qu'il y a plus optimisé que celle la... j'ose pas imaginer l'optimisation ma requête oracle avec ses deux petites lignes... Merci |
|
|
|
00
|
|
|
#6 | ||
|
Membre Expert
![]() ![]() Inscription : janvier 2010 Messages : 1 084 ![]() |
Bah en fait :
1/ Je pars du point de départ (jusque là rien d'extraordinaire 2/ par recursion, je cherche toutes les "bifurcation" possibles 3/ condition d’arrêt : j’arrête la récursion lorsqu'il existe dans la table sr1, une ultime étape pour arriver à bon port (cette étape n'est donc pas incluse dans sr2, et c'est pourquoi je la rajoute dans la requête finale). C'est le but du "NOT EXISTS" dans la partie recursive Il faut également s'assurer qu'on ne boucle pas... c'est l'objet de la clause de jointure avec le LIKE. Il n'est pas possible d'appeler plusieurs fois la CTE dans la partie récursive, donc au fur et à mesure de la récursion, je "stocke" dans un varchar la liste des étapes, et je vérifie pour chaque bifurcation que la partie récursive va ajouter, sije ne suis pas déjà passé par la destination(en vérifiant si la destination n'est pas dans la chaine). D’ailleurs dans cette chaine, je stock départ et arrivé (table 1 et table2) ce qui est inutile (on pourrait donc déjà commencer par là pour optimiser) Cependant, cette vérification pour éviter les boucles ne semble pas indispensable, puisque de toute façon la récursion s’arrête dès qu'on a trouvé un chemin(elle permet quand même d'éviter de traiter ces boucles inutiles). Cependant sans cela, et si on lance une requête sans chemin possible, la requête tournera indéfiniment (ou plutôt jusqu’à épuisement du serveur revoici la requête avec l’amélioration sur la vérification de boucle (ce qui au passage ne doit pas non plus changer la face du monde Code SQL :
|
||
|
|
10
|
|
|
#7 | ||
|
Futur Membre du Club
![]() Inscription : juin 2007 Messages : 69 ![]() |
salut,
merci pour les explications, j'y vois déja un peu plus clair. Sinon en faisant des nouveaux test, il s'avère que la requête ne me renvoie pas les bons résultats. En fait, c'est pas tout à fait ça car il me retourne le bon résultat et il y ajoute des chemins en rapport avec la "table2" passée en paramètre. Voila les données utilisé avec la requête : Code :
Code :
gwmet.numgwmet = Vue_Fil.metgwvue AND gwmet.langwmet = Vue_Fil.langwvue AND Vue_Fil.tvugwvue = 'F' AND ETA_Fil_P.occgtpar = Vue_Fil.etagwvue AND ETA_Fil_P.padgtpar = 'ETA' Code :
gwmet.numgwmet = Vue_Fil.metgwvue AND gwmet.langwmet = Vue_Fil.langwvue AND Vue_Fil.tvugwvue = 'F' |
||
|
|
00
|
|
|
#8 | ||
|
Membre Expert
![]() ![]() Inscription : janvier 2010 Messages : 1 084 ![]() |
Effectivement, je ne traite pas le cas particulier ou il existe un trajet direct...
au passage, j'ai ajouté dans l'ancrage table2 en plus de table1, et vous aviez visiblement fait un mix de mes deux requêtes pour la gestion des boucles. Revoici donc une requête qui gère le cas particulier, avec un UNION... là encore, il y a surement moyen de faire mieux, mais en revoyant la requête récursive... Code SQL :
|
||
|
|
10
|
|
|
#9 |
|
Membre Expert
![]() ![]() Inscription : janvier 2010 Messages : 1 084 ![]() |
hmmm
en fait, plus je la relis, et moins je la trouve correcte.... disons qu'elle doit plus ou moins fonctionner.... ![]() J'y rejette un oeil... |
|
|
00
|
|
|
#10 |
|
Futur Membre du Club
![]() Inscription : juin 2007 Messages : 69 ![]() |
Ok ca a l'air good maintenant, donc merci beaucoup.
je verrais pour l'optimisation plus tard (après les vac merci aieeeuuuuu. |
|
|
00
|
|
|
#11 | ||
|
Membre Expert
![]() ![]() Inscription : janvier 2010 Messages : 1 084 ![]() |
hmmm
c'est à vérifier, mais je pense qu'elle pourrait sortir tous les chemin possible en fait... Une autre requête plus académique : 1/ CTE qui cherche tous les chemins possibles à partir du point de départ, sans repasser plusieurs fois par le même point 2/ recherche du chemin le plus court parmi ceux qui mènent "à bon port" dans la requête finale. Contrairement à ce que je disais, je pense que mes requêtes précédentes calculaient bien tous les chemins possibles bref, testez celle-ci, je pense qu'elle est moins tordue : Code SQL :
|
||
|
|
00
|
|
|
#12 | ||
|
Membre Expert
![]() ![]() Inscription : janvier 2010 Messages : 1 084 ![]() |
C'est encore moi
Je pense finalement avoir trouvé une solution pour arrêter la récursion des qu'on a trouvé un chemin... mais au prix d'une fonction de fenêtrage... à comparer donc sur votre jeu de données complet par rapport à la requête précédente (il ne vous reste qu'a annuler vos vacances Code SQL :
|
||
|
|
10
|
|
|
#13 |
|
Futur Membre du Club
![]() Inscription : juin 2007 Messages : 69 ![]() |
Salut aieeeuuuuu,
Bon finalement je n'ai pas annulé mes vacances donc me revoilà. Je viens d'effectuer quelques test et ta dernière requête semble me retourner les résultats plus rapidement et avec un seul résultat à chaque fois. Du coup je pense rester sur celle la. Je te remercie pour ton aide. Bonne continuation. Ghosty |
|
|
00
|
Copyright © 2000-2012 - www.developpez.com