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

SQL Procédural MySQL Discussion :

Requete "trouver ordre" (stocké en relatif)


Sujet :

SQL Procédural MySQL

  1. #1
    Membre confirmé
    Inscrit en
    Septembre 2008
    Messages
    115
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 115
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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?

  2. #2
    ced
    ced est déconnecté
    Rédacteur/Modérateur

    Avatar de ced
    Homme Profil pro
    Gestion de bases de données techniques
    Inscrit en
    Avril 2002
    Messages
    6 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Gestion de bases de données techniques
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 059
    Par défaut
    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 et R
    Mes tutoriels et la FAQ MySQL

    ----------------------------------------------------
    Pensez aux balises code et au tag
    Une réponse vous a plu ? N'hésitez pas à y mettre un
    Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça

  3. #3
    Membre confirmé
    Inscrit en
    Septembre 2008
    Messages
    115
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 115
    Par défaut
    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

  4. #4
    Membre confirmé
    Inscrit en
    Septembre 2008
    Messages
    115
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 115
    Par défaut
    Bonjour ced,
    Je me demandais par curiosité si vous pouviez me dire 2 ou 3 mots sur votre phrase:

    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.

  5. #5
    Membre Expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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 : 1 919
    Billets dans le blog
    1
    Par défaut
    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 : 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
    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

  6. #6
    Membre confirmé
    Inscrit en
    Septembre 2008
    Messages
    115
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 115
    Par défaut
    Whaou!

    Je relie tout ça, et l'essaye.
    Merci

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Requete avec quote et double quote
    Par swissmade dans le forum VBA Access
    Réponses: 2
    Dernier message: 20/08/2007, 15h01
  2. Export requete texte -> Excel : erreur quote
    Par Sam 069 dans le forum VBA Access
    Réponses: 1
    Dernier message: 18/07/2007, 15h27
  3. [VBnet][Access] Requete imbriquee "insert + select"
    Par Fab62_ dans le forum Windows Forms
    Réponses: 3
    Dernier message: 06/03/2006, 13h58

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