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

Bases de données Discussion :

Ma requête SQL SELECT ne passe pas dans next()


Sujet :

Bases de données

  1. #1
    Membre régulier
    Inscrit en
    Décembre 2007
    Messages
    239
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 239
    Points : 92
    Points
    92
    Par défaut Ma requête SQL SELECT ne passe pas dans next()
    Bonjour,

    j'ai a nouveau un problème avec la gestion de ma base de données SQLite
    voici tout d'abord le code:
    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
    QList<QString> OpenFiche::recupValuePropriByCode()
    {
         QList<QString> list;
     
         QSqlQuery q;
         q.prepare("SELECT codeP, civilite, nomPropri, prenomPropri, dateNaissancePropri, "
                          "lieuxNaissancePropri, nationalite, adressePropri, CPPropri, "
                          "villePropri, TelDomPropri, telBurPropri, telPorPropri, mailPropri, tauxHonoraireHT, "
                          "assiette, periodeReglement, numMandat, entreLe, sortiLe, dernierRapportArreteLe, reglement, montantAcompte, "
                          "perioAcompte, dateDernierAcompte, montantDernierAcompte, banque, villeBanque, "
                          "codeBanque, codeGuichet, numCompte, cleRIB "
                   "FROM Proprietaire "
                   "WHERE codeP=:codeP");
         q.bindValue(":codeP", ligne->text());
         qDebug() <<ligne->text();
         q.exec();
         if(q.lastError().isValid())
              qDebug(qPrintable(q.lastError().text()));
         else
         {
             qDebug() <<"requete passée correctement";
             qDebug() <<q.executedQuery();
     
             q.first();
             int i=0;
             while(q.next())
             {
                  qDebug() <<"on est bien entré dans la boucle while!";
                  qDebug() <<q.value(i).toString();
                  list.append(q.value(i).toString());
                  i++;
             }
         }
         return list;     
    }
    Mon problème est que je ne passe pas une seule fois dans la boucle while(q.next()).
    Ce qui veut dire que q.next() est à false dès le début... donc je ne comprends pas trop ou est mon erreur...

    Merci d'avance!

    PS: j'ai préférer faire une requete SELECT comme je viens de le poster plutôt que de faire un SELECT * FROM qui à ce que j'ai pu en lire sur la doc, poserait problème sur l'ordre des valeurs. Ai-je bien fait?

  2. #2
    Membre expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Points : 3 266
    Points
    3 266
    Par défaut
    Salut,

    Oui, il est préférable de spécifier les champs dans toute requête.

    1. Vérifie que ta requête est correcte; vérifie là dans un soft qui te permet d'ouvrir une base sqlite et d'exécuter des requêtes (me semble que je t'en avais indiqué un il y a quelque temps) => ca te permettra de voir s'il y a une erreur dans la requête

    2.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    q.exec();
         if(q.lastError().isValid())
    devient:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if(!q.exec())
    { // dump de q.lastError().text()
    3. Comme je te l'ai dit précédemment, je me suis planté en te parlant d'appeller q.first() avant q.next(). C'est inutile. q.next() se placera sur le premier enregistrement automatiquement; et si ta requête renvoie plusieurs résultats, tu louperas le premier, ce qui est peut-être le cas ici

  3. #3
    Membre régulier
    Inscrit en
    Décembre 2007
    Messages
    239
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 239
    Points : 92
    Points
    92
    Par défaut
    Ma requête était bonne,

    Si je ne passais pas dans ma boucle c'est pour une raison toute simple (et donc, m'avais complètement échappé, j'en suis désolé )
    J'essayais de récupérer la ligne de ma table où codeP = 1 alors que mes lignes commençaient à codeP = 12 (j'avais oublié avoir Delete les lignes d'avant)

    Donc, ma requête sans résultat me renvoyait un next() vide, donc à false, ce qui explique que je ne passais même pas faire un p'tit tour dans le while.

    Je pensais que si codeP = 1 n'existait pas dans la table, j'aurai un renvois d'erreur, mais en fait absolument pas: la requete passe bien!
    Je fais donc chercher comment traiter un renvois NULL .

    Merci bien!

    PS: Pour first(), je pensais que c'était nécessaire du moment ou l'on avait plus d'une valeur de renvoyé dans la requête, je l'enlève tout de suite donc!

    Je change aussi q.lastError().isValid() mais j'aimerais comprendre en quoi c'est "moins bien" que if(!q.exec()) ?

  4. #4
    Membre régulier
    Inscrit en
    Décembre 2007
    Messages
    239
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 239
    Points : 92
    Points
    92
    Par défaut
    En fait non, j'ai toujours le même problème.

    Je ne passe pas dans ma boucle. J'ai fait un test pour savoir si next() est vide ou non, s'il est vide j'affiche un message d'erreur.

    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
    QList<QString> OpenFiche::recupValuePropriByCode()
    {
         QList<QString> list;
     
         QSqlQuery q;
         q.prepare("SELECT codeP, civilite, nomPropri, prenomPropri, dateNaissancePropri, "
                          "lieuxNaissancePropri, nationalite, adressePropri, CPPropri, "
                          "villePropri, TelDomPropri, telBurPropri, telPorPropri, mailPropri, tauxHonoraireHT, "
                          "assiette, periodeReglement, numMandat, entreLe, sortiLe, dernierRapportArreteLe, reglement, montantAcompte, "
                          "perioAcompte, dateDernierAcompte, montantDernierAcompte, banque, villeBanque, "
                          "codeBanque, codeGuichet, numCompte, cleRIB "
                   "FROM Proprietaire "
                   "WHERE codeP=:codeP");
         q.bindValue(":codeP", ligne->text());
         qDebug() <<ligne->text();
     
         if(!q.exec())
              qDebug(qPrintable(q.lastError().text()));
         else
         {
             qDebug() <<"requete passée correctement";
             qDebug() <<q.executedQuery();
     
             if(!q.next())
             {
                  QMessageBox::warning(this, "Erreur", 
                                "Ce numéro de proprietaire n'existe pas.");
             }
             else
             {
                  qDebug() <<"On est bien dans le else!";
                  int i=0;
                  while(q.next())
                  {
                        qDebug() <<"on est bien entré dans la boucle while!";
                        qDebug() <<q.value(i).toString();
                        list.append(q.value(i).toString());
                        i++;
                  }
             }
         }
     
        return list;     
    }
    La requête à l'air juste étant donné qu'elle passe bien sur le logiciel que tu m'avais passé.
    J'ai testé: si j'entre un codeP qui n'existe pas dans la base: ma QMessageBox s'affiche bien mais si le codeP existe, je ne passe quand même pas dans la boucle... Pourtant, le debug "On est bien dans le else" de mon code s'affiche bien.

  5. #5
    Membre expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Points : 3 266
    Points
    3 266
    Par défaut
    Ca me laisse penser que la requête ne renvoit pas de résultat. Peux-tu afficher QSqlQuery::numRowsAffected() (après l'exec, dans le else en somme) stp?

  6. #6
    Membre régulier
    Inscrit en
    Décembre 2007
    Messages
    239
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 239
    Points : 92
    Points
    92
    Par défaut
    En effet, le nombre de ligne renvoyée est égal à 0.

    je pensais que ça me renverrais un q.next() = false ...

    ... Et je pense avoir trouvé l'erreur: il dois me manquer les parenthèses entre "select" et "from". Sur l'éditeur de base données ça passe bien sans pourtant, d'ailleurs ce dernier me retourne bien une ligne: ma ligne de codeP = 1.

    je suis sur de ma requête étant donné que j'ai fais un copier/coller d'un qDebug de cette dernière, j'ai juste enlever les double quotes de chaque coté et ai remplacé "WHERE codeP = ?" (le "?" étant généré par le prepare() + bindValue() je suppose) par "WHERE codeP = 1"


    EDIT: non, les parenthèses me retournent une erreur de synthaxe...
    j'ai essayé de changer : q.bindValue(":codeP", ligne->text());
    en : q.bindValue(":codeP", ligne->text().toInt());
    mais pas de changement.
    J'ai aussi essayé de passer outre un bindValue() en entrant ma requete avec:
    WHERE codeP=1

    Pas de changement, j'ai toujours aucune ligne de renvoyée.

  7. #7
    Membre régulier
    Inscrit en
    Décembre 2007
    Messages
    239
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 239
    Points : 92
    Points
    92
    Par défaut
    J'ai encore un peu chercher: je doute qu'un q.record() me serve à quelque chose étant donné que de toute façon: je n'entre pas dans mon while...

  8. #8
    Membre expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Points : 3 266
    Points
    3 266
    Par défaut
    Raaah bon sang, je suis mieux réveillé qu'hier soir:
    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
             if(!q.next())
             {
                  QMessageBox::warning(this, "Erreur", 
                                "Ce numéro de proprietaire n'existe pas.");
             }
             else
             {
                  qDebug() <<"On est bien dans le else!";
                  int i=0;
                  while(q.next())
                  {
                        qDebug() <<"on est bien entré dans la boucle while!";
                        qDebug() <<q.value(i).toString();
                        list.append(q.value(i).toString());
                        i++;
                  }
             }
    Combien de next sont exécutés? Par déduction, quand tu cherches à entrer dans le while, tu devrais récupérer à partir de quel index d'enregistrement?

    Le next() va chercher le record, pas uniquement te dire s'il y en a un suivant!

  9. #9
    Membre régulier
    Inscrit en
    Décembre 2007
    Messages
    239
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 239
    Points : 92
    Points
    92
    Par défaut
    Je ne comprends pas trop si dans ton poste: tes questions ont pour but de me mettre sur la voix, ou sont-elles bien des questions à part entière (non rhétorique)?

    Je ne passe pas une seule fois dans le while, donc next n'est pas executé une seule fois: je suppose que c'est justement parce que j'ai next = false dès le départ : ce qui entraine (étant donné que next() se place, comme first, au premier record) que je n'ai pas de record à faire chercher par next.

    Je voudrai récupéré à partir de l'enregistrement 0 jusqu'au 31ième puisque j'ai 32 colonnes dans ma table, mais qu'importe, puisque next() se place au début ?

    Y'a surement quelque chose qui m'échappe dans ton aide...

    La solution est-elle la méthode record() et ensuite d'utiliser indexOf ?

  10. #10
    Membre expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Points : 3 266
    Points
    3 266
    Par défaut
    C'était pour te mettre sur la voie en te faisant réfléchir à ce qu'il se passe

    Bref, je vais déplier:
    0. exécution de la requête, le recordset est initialisé et l'index de l'enregistrement courant est -1 (enregistrement invalide disons)

    1. if(!q.next())
    l'enregistrement courant est déplacé d'un cran. Vu que précédemment il était invalide, cette appel sélectionne l'enregistrement 0 comme actif

    2. while(q.next())
    Ici aussi next() est exécuté. L'enregistrement précédent était celui que tu cherchais. Demander à la requête d'avancer à l'enregistrement suivant renvoie faux puisqu'il n'y a plus d'enregistrements (si tu en avais au moins 2 ce serait "bon", dans le sens où tu zapperais toujours la première ligne mais passerait tout de même dans ton while)

  11. #11
    Membre régulier
    Inscrit en
    Décembre 2007
    Messages
    239
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 239
    Points : 92
    Points
    92
    Par défaut
    Alors il y a autre chose que je ne comprends pas:
    Quand tu parles d'enregistrement: tu parles de ma ligne (donc = 1 enregistrement) ou de mes valeurs retournées (donc 32 enregistrements)

    Car si enregistrement = 32, le fait de passer la premiere valeur ne me génerai pas pour entrer de le while, comme toi même me l'a dis (enfin, du moins, c'est ce que je crois comprendre )

    J'ai essayé d'utiliser la méthode seek() juste avant le while, en l'utilisant de la sorte:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    q.seek(0);
                  while(q.next())
                  {
    c'est donc sensé me repositionner sur le premier record, mais j'ai pas plus de résultat

    Sinon pour ton 2.
    2. while(q.next())
    Ici aussi next() est exécuté. L'enregistrement précédent était celui que tu cherchais. Demander à la requête d'avancer à l'enregistrement suivant renvoie faux puisqu'il n'y a plus d'enregistrements (si tu en avais au moins 2 ce serait "bon", dans le sens où tu zapperais toujours la première ligne mais passerait tout de même dans ton while)
    Je ne suis pas sûr que q.next() soit executé si next() = false ?
    Sinon, je parcourerais au moins une fois la boucle non? Or ce n'est pas le cas de toute façon sinon mes qDebug dans le while s'afficheraient au moins une fois...

    Je ne comprends toujours pas donc

    Et aussi: tu avais parlé de numRowsAffected(), pourquoi me retourne t'il toujours 0 ? J'ai surtout l'impression que mon problème n'a rien à voir avec next()

  12. #12
    Membre expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Points : 3 266
    Points
    3 266
    Par défaut
    Un enregistrement en base de donnée, c'est une ligne.
    Le seek il faudrait le faire sur l'enregistrement invalide. Or ce que tu fais c'est:
    1. seek(0) => revient au premier enregistrement
    2. while(q.next()) => passe à l'enregistrement suivant => y'en a pas => ne rentre pas dans le while

    Pour évaluer la condition du while, la fonction est obligatoirement exécutée, comment veux-tu que le while sache si next() s'évalue à true ou false si cette fonction n'est pas exécutée?

    La, ça devient plus un problème de lacune C++ qu'un problème de SGBD :s

  13. #13
    Membre expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Points : 3 266
    Points
    3 266
    Par défaut
    Citation Envoyé par Somato Voir le message
    Et aussi: tu avais parlé de numRowsAffected(), pourquoi me retourne t'il toujours 0 ? J'ai surtout l'impression que mon problème n'a rien à voir avec next()
    C'est peut-être pas supporté par SQLite, ça ne m'étonnerait pas.

  14. #14
    Membre régulier
    Inscrit en
    Décembre 2007
    Messages
    239
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 239
    Points : 92
    Points
    92
    Par défaut
    Un enregistrement en base de donnée, c'est une ligne
    En effet, du coup je comprends mieux pourquoi je n'avais pas de résultat

    Pour évaluer la condition du while, la fonction est obligatoirement exécutée, comment veux-tu que le while sache si next() s'évalue à true ou false si cette fonction n'est pas exécutée?
    En effet aussi

    Mais du coup, si je n'ai qu'un seul enregistrement, je ne parcourrai le while qu'une seule fois... Je vois mal comment récupérer toutes mes valeurs du coup ?

    Value(0) va donc me retourner toutes les valeurs de mon select?
    EDIT: Après relecture de la doc, apparement non... j'attends de tester quand même...

  15. #15
    Membre expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Points : 3 266
    Points
    3 266
    Par défaut
    Citation Envoyé par doc de QSqlQuery::value
    Returns the value of field index in the current record.
    Tu as un enregistrement actif qui contient 1..n champs. Si tu veux tous les récupérer, faut itérer. Ou mieux mais plus verbeux, les récupérer par leur nom (en récupérant l'enregistrement actuel avec QSqlQuery::record() puis QSqlRecord::value(QString))

  16. #16
    Membre régulier
    Inscrit en
    Décembre 2007
    Messages
    239
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 239
    Points : 92
    Points
    92
    Par défaut
    Oui, j'avais remarqué pour la méthode record(), mais en quoi est-elle mieux?

  17. #17
    Membre expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Points : 3 266
    Points
    3 266
    Par défaut
    Comme je l'ai écrit, elle te permet d'accéder au champ par leur nom et non plus par un index. C'est plus sûr.

  18. #18
    Membre régulier
    Inscrit en
    Décembre 2007
    Messages
    239
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 239
    Points : 92
    Points
    92
    Par défaut
    Je pensais qu'il y aurait quelque chose de plus "obscure" à mes yeux

    En tout cas merci beaucoup, ça fonctionne bien maintenant

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

Discussions similaires

  1. [MySQL] Requête SQL qui ne passe pas (UPDATE)
    Par ZeWiz dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 04/09/2014, 13h25
  2. [MySQL] Déboguer requête sql qui ne passe pas
    Par Kamoo dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 21/02/2013, 11h09
  3. erreur de requête SQL avec ASP mais pas dans Access
    Par csszzen dans le forum Langage SQL
    Réponses: 6
    Dernier message: 16/03/2007, 09h07
  4. Ctrl -] ne passe pas dans une console avec vim
    Par Celelibi dans le forum Applications et environnements graphiques
    Réponses: 4
    Dernier message: 10/03/2006, 13h35
  5. Réponses: 8
    Dernier message: 26/10/2005, 03h52

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