Précédent   Forum des professionnels en informatique > Bases de données > MySQL > SQL Procédural
SQL Procédural Forum d'entraide sur les triggers, les procédures stockées et les fonctions en MySQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 29/04/2011, 12h01   #1
Nouveau Membre du Club
 
Inscription : septembre 2008
Messages : 115
Détails du profil
Informations forums :
Inscription : septembre 2008
Messages : 115
Points : 28
Points : 28
Par défaut Requete "trouver ordre" (stocké en relatif)

Je suis en train de bloquer sur un problème d'ordre stocké en relatif.

Je vais simplifier mon problème en ne gardant que le strict minimum
J'ai une table qui sert à organiser mes étapes:

Code :
1
2
3
4
5
6
 
id_etape    |     nex_id_etape
   104       |          320
   210       |          220
   220       |          104
   320       |          2
Je voudrais récupérer l'ordre dans lequel ses étapes s'enchainent.
Donc à priori:
210->220->104->320->2

J'ai bien une solution récursive en utilisant le language dans lequel je développe. Mais c'est assez couteux...

Avez-vous un système de requete unique à me conseiller?
Vilukariok est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2011, 14h35   #2
ced
Rédacteur/Modérateur

 
Avatar de ced
 
Homme Cédric Duprez
Inscription : avril 2002
Messages : 3 823
Détails du profil
Informations personnelles :
Nom : Homme Cédric Duprez
Âge : 36
Localisation : France, Loiret (Centre)

Informations professionnelles :
Secteur : Agroalimentaire - Agriculture

Informations forums :
Inscription : avril 2002
Messages : 3 823
Points : 6 440
Points : 6 440
Bonjour,

Pas sous MySQL, malheureusement.
Sauf à passer par une fonction utilisateur, mais je doute que les performances soient meilleures qu'en passant par le langage dans lequel tu développes.

ced
__________________
Rédacteur / Modérateur SGBD
Mes tutoriels et la FAQ MySQL

----------------------------------------------------
Pensez aux balises code et au tag
Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça
ced est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2011, 15h20   #3
Nouveau Membre du Club
 
Inscription : septembre 2008
Messages : 115
Détails du profil
Informations forums :
Inscription : septembre 2008
Messages : 115
Points : 28
Points : 28
C'est bien ce que je craignais.
Une fonction récursive en MySql va être trop couteuse.
Je crois que je vais devoir faire le 'tri' sur la couche Supérieur (langage Delphi)
Merci quand même.

Et je reste ouvert à toute proposition
Vilukariok est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/05/2011, 18h02   #4
Nouveau Membre du Club
 
Inscription : septembre 2008
Messages : 115
Détails du profil
Informations forums :
Inscription : septembre 2008
Messages : 115
Points : 28
Points : 28
Bonjour ced,
Je me demandais par curiosité si vous pouviez me dire 2 ou 3 mots sur votre phrase:

Citation:
Pas sous MySQL, malheureusement.
Sauf à passer par une fonction utilisateur, mais je doute que les performances soient meilleures qu'en passant par le langage dans lequel tu développes.
Vilukariok est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/05/2011, 04h45   #5
Membre Expert
 
Homme Eric Dureuil
Développeur informatique
Inscription : avril 2011
Messages : 843
Détails du profil
Informations personnelles :
Nom : Homme Eric Dureuil
Localisation : France, Isère (Rhône Alpes)

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

Informations forums :
Inscription : avril 2011
Messages : 843
Points : 1 318
Points : 1 318
Salut,

C'est vrai que sous un plus gros sgbd genre oracle, tu aurais pu faire une requête hiérarchique pour résoudre ton pb...

ici tu dois donc faire du récursif soit côté mysql (255 niveaux de récursion maxi) grâce aux procédures stockées (les fonctions stockées ne permettent pas la récursion actuellement), soit côté langage (php par exemple), soit en faisant un mixe des 2 pour améliorer les performances...

Idée: En faisant bosser mysql avec une récursion tu va minimiser les échanges langage-mysql. Mais comme tu as la limitation des 255 lvl de récursion, selon le nombre d'étapes que tu as eu:
  • la liste contient 255 entrées, on les récupère et le php relance la procédure sur le dernier identifiant d'étape obtenu et on ajoute le tableau de valeurs obtenues à l'éventuel tableau précédemment obtenu.
  • La liste contient moins de 255 entrées, tu n'as plus qu'à exploiter les résultats.

La procédure stockée:
3 astuces:
  • On va forcer le niveau de récursion max à 255, il est à 0 à l'origine...
  • On va intercepter l'erreur de récursion maxi dépasser pour forcer le retour, ou, plus simple, arrêter la récursion avant, par exemple à 254 (on devra donc, côté php détecter si la liste de valeur a une longueur <254 pour être cohérent)...
  • On concatène les résultats sous forme d'une chaine de caractère vu qu'on peut pas retourner de tableau et qu'on veut pas renvoyer un résultat à buffériser par étape.
Code sql :
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
delimiter |
DROP procedure IF EXISTS chemin|
DROP procedure IF EXISTS parcourt|
 
CREATE procedure parcourt(IN pos int(4))
begin
declare t bool;
declare i int(4);
SET @recursion=@recursion+1;
SELECT count(id)>0,nex_id_etape INTO  t,i FROM etapes WHERE id_etape=pos;
IF i<254 AND t then
call parcourt(i);
end IF;
SET @l_chemin=concat_ws(',',pos,@l_chemin);
end|
 
CREATE procedure chemin(IN depart int(4))
begin
SET @@max_sp_recursion_depth=255;
SET @l_chemin=NULL;
SET @recursion=0;
call parcourt(depart);
SELECT @recursion+1 AS "étapes" ,concat_ws (',',depart,@l_chemin) AS "chemin";
end|
delimiter ;

à chaque appel tu obtiens donc le nombre d'étapes du chemin et la chaine le décrivant que tu n'a qu'à exploser en tableau en te basant sur la ',' comme séparateur..., si tu as au moins 254 éléments tu peux alors relancer le traitement sur le dernier (ne pas oublier de le supprimer du tableau que tu obtiendras pour ne pas avoir de doublon avec le tableau précédent)...

Voilà une idée par exemple
ericd69 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 16/05/2011, 11h15   #6
Nouveau Membre du Club
 
Inscription : septembre 2008
Messages : 115
Détails du profil
Informations forums :
Inscription : septembre 2008
Messages : 115
Points : 28
Points : 28
Whaou!

Je relie tout ça, et l'essaye.
Merci
Vilukariok est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 08h50.


 
 
 
 
Partenaires

Hébergement Web