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 Delphi Discussion :

Problème de requête dans une boucle avec ADOQuery


Sujet :

Bases de données Delphi

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2003
    Messages : 31
    Points : 24
    Points
    24
    Par défaut Problème de requête dans une boucle avec ADOQuery
    Bonjour,

    J'ai un problème avec ADO.

    J'ai une boucle While qui contient une requête :

    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
     
    while (Flag) or (Count<=22) do
    begin    
     
    [...]
     
       With qSelectManufacturers do begin
            Close;
            Connection:=ADOConnection1;
            CursorLocation:= clUseClient;
            LockType:= ltOptimistic;
            CursorType:= ctStatic;
            SQL.Clear;
            SQL.Add('Select * FROM manufacturers WHERE manufacturers_name = :MANU');
            Parameters.ParamValues['MANU']:= StringReplace(Msg[2],'"','',[rfReplaceAll]);
            Open;
       end;
    end;
     
    [...]
    Quand je passe la 2ème fois dans la boucle ca me fait une "Erreur non spécifiée". J'ai aussi testé avec Active mais bon, j'ai cru lire sur ce forum que c'était exactement pareil

    J'ai essayé avec un Requery également :

    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
     
          With qSelectManufacturers do begin
            Connection:=ADOConnection1;
            CursorLocation:= clUseClient;
            LockType:= ltOptimistic;
            CursorType:= ctStatic;
            SQL.Clear;
            SQL.Add('Select * FROM manufacturers WHERE manufacturers_name = :MANU');
            Parameters.ParamValues['MANU']:= StringReplace(Msg[2],'"','',[rfReplaceAll]);
     
            if dejapasse then
            begin
              Requery();
            end else
            begin
              Open;
              dejapasse:=true;
            end;
          end;
    la var "dejapasse" est un bool que j'initialise a false pour faire un Requery dès le 2ème passage dans ma boucle

    Et la, je fais 3-4 passage puis j'ai une erreur qui me dit

    Runtime Error
    Program : T:\Projets\import\import.exe

    R6025
    - pure virtual function call
    Je me disais que cela pourrais avoir un rapport avec le serveur qui n'arriverait pas a suivre mais bon, ca me le fais même en Pas-à-pas. Je pense plutot que c'est moi qui ai mal codé mon truc

    Voila j'espère que qqn saura m'aider car je suis vraiment bloqué.

    Merci d'avance

  2. #2
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut
    A moins de créer dynamiquement le composant, il est inutile de reconfigurer ton TAdoQuery, il te suffit dfe la faire une fois pour toutes directement dans le composant.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     Connection:=ADOConnection1;
     CursorLocation:= clUseClient;
      LockType:= ltOptimistic;
      CursorType:= ctStatic;
    Sinon il serait bien d'avoir le type de base de données auquel tu te connectes.
    Et si possible, d'avoir aussi le code avant le while qui peut être la cause de ton problème.
    Modérateur Delphi

    Le guide du bon forumeur :
    __________
    Rayek World : Youtube Facebook

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2003
    Messages : 31
    Points : 24
    Points
    24
    Par défaut
    Merci pour votre réponse.

    Ok, je vais sortir les ligne des configuration de la boucle.

    Je me connecte sur une base MySQL 5 via le driver ODBC 3.51

    En fait avant ma boucle, je n'ai pas grand chose, juste une routine qui me parse un fichier csv et me met le tout dans un TStrings.

    En tout cas, rien qui se connecte a la BDD. Enfin sauf maintenant, j'ai les lignes de codes que j'ai sorti de la boucle

    Juste encore une chose, j'utilise

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    StringReplace(Msg[2],'"','',[rfReplaceAll]);
    parce que les données dans mon fichier csv sont entourée chacune de guillements.

    J'ai essayé de passer la valeur "brute", avec les guillemets et apparement je n'ai plus d'erreur, mais par contre, quand je refais un nouveau tour dans ma boucle, je passe sur le Requery pour rafraichir les resultats de ma requetes et la, il ne retourne rien.

    Je sais pas si je suis clair, dites le moi si jamais et j'essaierai de trouver une meilleure explication.

    Merci

  4. #4
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut
    Vire le système que tu as fait avec le Requery, ca ne te sert à rien.

    Sinon je voudrais savoir à quoi ca te sert de boucler sur une requete Select et de ne rien faire après avec ?

    Derniere chose, il n'y a pas mieux que les pilotes ODBC 3.51 ? Car je ne suis pas sûr qu'il soit correctement compatible avec MySQL5.
    J'ai vu il y a quelques temps que des drivers ODBC pour la version 5 existait (en béta mais ca fait un bon moment déjà donc peut être qu'ils sont en version finale)
    Modérateur Delphi

    Le guide du bon forumeur :
    __________
    Rayek World : Youtube Facebook

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2003
    Messages : 31
    Points : 24
    Points
    24
    Par défaut
    En fait, je suis dans la situation suivante :

    J'ai un fichier CSV avec des articles et leur différentes "propriétés" (marques, prix,...). Chaque propriété est entourée de guillemets (") et séparée par une virgule.

    Je dois prendre chaque ligne d'article et l'inserer dans une BDD MySQL (pour un E-shop).

    Or dans ces lignes d'articles, il y en un élément qui est le nom du fabriquant. Et moi dans la BDD pour mon e-shop, j'ai bien sur une table Fabriquants avec une clé étrangère dans la table des produits.

    donc quand je parcours mon fichiers csv, je procède comme ceci :

    - Je met chaque ligne de mon fichier dans un TStrings "Msg" (il y a 21 éléments en tout" --> Msg[0] => Id, Msg[1]=>Fabriquant, Msg[2]=>Modèle,...)

    - A la fin de ma ligne, je rajoute l'id du fabriquant. Mais comme vu en dessus, je n'ai que le nom donc je fais une requête (qSelectManufacturers) pour récupérer l'id. (C'est le code que je vous ai mis dans mon 1er message, mais il manque un bout en effet, excusez-moi, j'était légèrement stress et j'ai pas fait vraiment gaffe a ce que j'ai écrit )

    Ensuite voila ce que je fais juste après mon "if dejapasse then..."

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if (qSelectManufacturers.RecordCount>0) then
              Msg.Add(qSelectManufacturers.FieldByName('manufacturers_id').AsString)
            else
              Msg.Add(inttostr(InsertManufacturers(StringReplace(Msg[2],'"','',[rfReplaceAll]))));
    Donc si un fabriquand est trouvé avec le nom que je lui ai passé en param, j'ajoute son ID a la fin de ma TStrings sinon j'appelle une fonction InsertManufacturers(nom_du_fabriquant) qui ajoute le fabriquant dans la base et me retourne son ID, et la pareil je l'ajoute dans mon TStrings

    J'ai mis un requery pour reactualiser le nombre de résultat que retourne mon SELECT donc. Sinon il est toujours a 0.

    Mais vous dites que le système avec le Requery ne sert a rien, j'imagine que c'est la variable dejapasse dont vous parlez ? Comment puis-je faire autrement ? Si je met simplement un Open, ca me retourne toujours le meme resultat et si je met un Requery, ca me met une erreur au 1er passage.

    Sinon je vais vérifier s'il n'existe pas de drivers > 3.51 alors en effet.

    Merci bcp pour votre aide.

  6. #6
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut
    Pourquoi élimines tu les " au moment de la requete, tu peux le faire bien avant sur l'intégralité du TStrings.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Msg.text := StringReplace(Msg.text,'"','',[rfReplaceAll]);
    Après il ne te reste plus qu'a passer ta valeur en paramètre normalement.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     Parameters.ParamValues['MANU']:= Trim(Msg[2]); // le trim pour virer espace et caractère spéciaux
    Modérateur Delphi

    Le guide du bon forumeur :
    __________
    Rayek World : Youtube Facebook

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2003
    Messages : 31
    Points : 24
    Points
    24
    Par défaut
    Ok je vais essayer ca, merci.

    Par contre, auriez-vous un lien ou pourriez-vous me dire comment je peux faire mon code pour une requête dans une boucle avec Requery() ?

    Si je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    While ... do 
    begin
     
      Close;
      Parameters.ParamValues['MANU']:=Trim(Msg[2]);
      Open;
      Requery();
     
    end;
    Est-ce que ca devrait fonctionner ? Parce que la ca me fait toujours une erreur non spécifié et j'aimerai bien savoir si c'est le drivers ou le code qui foire.

    Merci

  8. #8
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut
    Pourquoi persistes tu avec Requery ??
    Requery est un peu comme si tu faisais Close puis Open sur ta requete, donc ca ne sert à rien surtout dans le fonctionnement que tu fais.

    Si tu n'as pas de résultat au niveau de ta requete c'est que tu passes mal ton paramètre c'est tout.

    Dans la base de données "manufacturers_id" est de quel type ? integer/string/autres ?
    Modérateur Delphi

    Le guide du bon forumeur :
    __________
    Rayek World : Youtube Facebook

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2003
    Messages : 31
    Points : 24
    Points
    24
    Par défaut
    Re-bonjour.

    Désolé de répondre si tardivement.

    J'ai trouvé la solution a mon problème, il s'agissait bien d'un problème de drivers ==> http://bugs.mysql.com/bug.php?id=28065

    Apparement la version 3.51.14 provoque une violation d'accès quand on fait plusieurs opération d'ouverture/fermeture.

    Or moi ca me le faisait justement sur un Requery ou sur un open/close dans un boucle. Je suis donc passé a la version 3.51.12 et tout fonctionne nickel.

    Et sinon, du coup j'ai bien viré mon Requery pour un close/open du coup.

    Donc voila, merci quand même pour votre aide Malatar !

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 28/08/2006, 14h16
  2. Réponses: 4
    Dernier message: 15/06/2006, 11h05
  3. Problème de SCANF dans une boucle WHILE
    Par FidoDido® dans le forum C
    Réponses: 4
    Dernier message: 30/12/2005, 18h42
  4. Réponses: 4
    Dernier message: 16/12/2005, 17h25
  5. [Conception] Problème de test dans une boucle while
    Par Cyrius dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 26/11/2005, 19h07

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