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

SQLite Discussion :

Probleme sqlite et boucle recursive


Sujet :

SQLite

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 8
    Par défaut Probleme sqlite et boucle recursive
    Salut,
    Je ne parviens pas à faire fonctionner correctement ma methode recursive incluant des appels sqlite. Tout est dans le fait de trouver comment faire en sorte que mes statements sqlite soient initialisés correctement à chaque passage.

    Prenons l'exemple suivant :


    Si je place un reset sur les lignes A et B comme dans le code ci-dessous, la methode affiche les feuilles de la première branche (Robin et Ulysse) et puis s'arrête.
    Si je ne place pas un reset sur la ligne B, la methode me montre les elements du premier niveau (Jack, John, Peter) car lorsque la methode veut trouver les enfants de Jack et Elisabeth, elle recoit John comme reponse car c'est toujours le prochain element que mon children_statement à a donner.

    Si je ne place de reset ni en A ni en B, la methode me montre les elements du premiere niveau (Jack, John, Peter) mais ne trouve aucun partnenaire a ces messieurs car le partner_statement ne fournit plus de réponse vu que Louis à une seule épouse.

    J'ai aussi essayer de recreer le sqlite3_prepare des 2 statements a chaque passage en ne verifiant pas si le statement etait nil ou non mais ca a le meme effet que dans le premier cas precedent : la methode descend au font de la premiere branche et puis s'arrete.

    Quelqu'un a-t-il une idée sur la facon de faire fonctionner correctement cette recursion a base de sqlite ?

    Un résumé du code de ma méthode (en objective-c) se trouve ci-dessous.
    Merci d'avance.
    Didier

    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
     
    -(NSString *)exportDescendantsOf:(NSInteger)aPrimaryKey withSex:(NSString*)aSex inText:(NSString*)text {
     
         GeneaAppDelegate *appDelegate = (GeneaAppDelegate *)[[UIApplication sharedApplication] delegate];
         NSString *tempFamText = [NSString string];
         NSString *tempSpouseChildText = [NSString string];
     
    A               sqlite3_reset(male_partners_statement);
              if (male_partners_statement == nil) {
                   static char *male_partnersSql = "SELECT relation_pk, female_partner_id FROM relation WHERE male_partner_id = ? ORDER BY position";
                   if (sqlite3_prepare_v2(appDelegate.database, male_partnersSql, -1, &male_partners_statement, NULL) != SQLITE_OK)
                        NSAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(appDelegate.database));
              }
     
              sqlite3_bind_int(male_partners_statement, 1, aPrimaryKey);
              NSLog(@"Descendants of : %d",aPrimaryKey);
     
              while (sqlite3_step(male_partners_statement) == SQLITE_ROW) {
                   int relation_pk = sqlite3_column_int(male_partners_statement, 0);
                   int female_partner_id = sqlite3_column_int(male_partners_statement, 1);
    ...
                   //Export the childs               
    B                       sqlite3_reset(children_statement);
                   if (children_statement == nil) {
                        NSLog(@"children_statement is nil");
                        static char *childrenSql = "SELECT pk, firstname, lastname, sex FROM person WHERE father_id=? AND mother_id=? ORDER BY position";
                        if (sqlite3_prepare_v2(appDelegate.database, childrenSql, -1, &children_statement, NULL) != SQLITE_OK)
                             NSAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(appDelegate.database))
                   }
     
                   sqlite3_bind_int(children_statement, 1, aPrimaryKey);
                   sqlite3_bind_int(children_statement, 2, female_partner_id);
                   NSLog(@"Binding %d %d to children_statement", aPrimaryKey,female_partner_id);
     
                   while (sqlite3_step(children_statement) == SQLITE_ROW) {
                        NSLog(@"Going through children of %d %d",aPrimaryKey,female_partner_id);
                        int childPrimaryKey = sqlite3_column_int(children_statement, 0);
                        NSLog(@"Child of %d %d primaryKey : %d", aPrimaryKey,female_partner_id,childPrimaryKey);
    ...
     
                   }
                   NSLog(@"No more kids to treat");
              }
     
     
    }

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 8
    Par défaut
    Véritablement personne avec des connaissances en terme d'appels sqlite dans des boucles recusives ?

    Peut-etre intéressant à noter, il y a bien un appel
    tempSpouseChildText = [self exportDescendantsOf:childPrimaryKey withSex:childSex inText:tempSpouseChildText];
    dans la boucle interne "children".

    C'est juste qu'en nettoyant un peu le code pour le mettre sur le forum, j'ai été jusqu'à effacer l'appel récursif lui-même :-)

    Il n'en reste pas moins que le problème est toujours là !

    Merci d'avance pour le temps que vous pourriez investir à examiner ce problème.

    Cordialement,

    Didier

  3. #3
    Membre expérimenté

    Inscrit en
    Décembre 2004
    Messages
    169
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 169
    Par défaut
    Bonjour,

    On peut dire que j'en ai bavé à comprendre ton problème...
    Enfin, avec un petite basounette et quelques ordres sql je me suis fait une idée.

    Ton problème est en fait très simple : tu ne fais pas de récursivité et tu t'attends à en obtenir ! Je m'explique.

    En gros, une récursivité c'est une fonction qui s'appelle elle même.
    (je sais, c'est bien ce que tu dis avoir fait, mais je le rappelle pour ceux qui ne suivent pas, car le comportement des réinitialisation des requêtes prouvent que ton problème vient de là).


    Soit la fonction exportDescendantsOf() :
    Dans un premier temps, ta fonction devrait créer une requête male_partners_statement afin d'obtenir la personne female_partner_id connaissant son conjoint identifié par aPrimaryKey.
    Cette requête doit te ramener de 0 à n id de personne.

    Pour chaque id ramené, il te faut trouver les enfants du couple. C'est la requête children_statement qui te retournera de 0 à n enfants.

    Pour chaque enfant mâle trouvé (car ta requête male_partners_statement est ainsi construite), tu dois de nouveau appeler la fonction exportDescendantsOf() avec l'id de l'enfant mâle passé en paramètre.

    Il va sans dire que les variables et les requêtes utilisées dans ta fonction doivent avoir une portée locale. En aucun cas tu ne pourras utiliser un male_partners_statement ou un children_statement déclarés de façon globale. Sinon, lors de ton second appel à la fonction, tu écraserai les valeurs et curseurs du premier appel. (NB: bingo ! c'est surement là la source de ton problème !)

    Si ton arbre généalogique fait 10 niveaux, tu auras au plus profond de l'arbre 10 * 2 requêtes d'ouvertes en même temps.

    A la sortie de la fonction, les deux requêtes doivent être fermées et la mémoire libérée.

    Je te conseille donc de rechercher une solution sans la récursivité. Il y a plein de méthodes, l'une d'entre elles est la représentation intervallaire.
    Tu trouveras des idées ici :
    http://sqlpro.developpez.com/cours/arborescence/

    Bon courage
    ++

    PS : pour ton exemple, cela doit donner :

    niveau 1 :
    pere : 1, mere 2
    fils : 3 (Jack)

    niveau 2 :
    pere : 3 (Jack)
    mere : 4
    fils : 9 (Didier)

    niveau 3 :
    pere : 9 (Didier)
    mere : 10
    fils : 15 (Robin)

    niveau 4 :
    Robin n'a pas de fils
    fin

    suite du niveau 3 :
    fils : 16 (Ulysse)

    niveau 4 :
    Ulysse n'a pas de fils
    fin

    suite du niveau 3 :
    fin

    suite du niveau 2 :
    fils : 11 (Pascal)

    niveau 3 :
    pere : 11 (Pascal)
    mere : 12
    fils : 17 (Adrien)

    niveau 4 :
    Adrien n'a pas de fils
    fin

    etc...

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 8
    Par défaut
    Bigane,

    Un très grand merci pour le temps passé sur ma question.
    Tu as parfaitement déchiffré l'algorithme et en plus tu m'as apporté la réponse.

    Il a suffit que je ramène la déclaration de mes statements localement pour que tout fonctionne.

    Etant donné que la profondeur de mes arbres ne devrait pas être trop profonde je reste pour l'instant sur de la récursivité mais ton article sur la méthode non récursive est églalement très intéressant.

    Encore un grand merci.

    Cordialement,

    Didier

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

Discussions similaires

  1. [VBA-E] PRobleme avec une boucle DO..LOOP WHILE
    Par AliochaBada dans le forum Macros et VBA Excel
    Réponses: 11
    Dernier message: 31/07/2006, 01h04
  2. Probleme avec Make -->[all-recursive] Erreur 1
    Par lolodelp dans le forum Installation
    Réponses: 3
    Dernier message: 18/04/2006, 23h41
  3. Probleme optimisation de boucles
    Par panda31 dans le forum C
    Réponses: 13
    Dernier message: 06/04/2006, 15h10
  4. Réponses: 3
    Dernier message: 02/03/2006, 11h25
  5. Probleme d'insertion de fichiers – Boucle recursive ?
    Par LLEJEUNE1 dans le forum Général Python
    Réponses: 1
    Dernier message: 09/02/2006, 17h35

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