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

Composants VCL Delphi Discussion :

Problème de requête avec le composant TADOQuery !


Sujet :

Composants VCL Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé

    Inscrit en
    Février 2005
    Messages
    356
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 356
    Par défaut Problème de requête avec le composant TADOQuery !
    Bonjour tout le monde !

    Voilà j'ai un GROS problème avec le composant ADO de Delphi 6. (BDD MySQL v5.1.33)

    Mon 1er problème que j'ai réussi à contourner :
    Lorsque j'effectue cette requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT COALESCE(CodeClient, -1) CodeClient
      FROM PLANNING
     WHERE CodePersonnel = :CodePersonnel
    - Lorsque j'effectue un FieldByName('CodeClient').AsInteger, Delphi me retourne 1 au lieu de -1 lorsque le champ CodeClient est null.
    J'ai essayé en mettant COALESCE(CodeClient, -9) CodeClient et Delphi me retourne 9 au lieu de -9. En bref, il retourne la valeur absolue.
    => Pourquoi ? (J'ai contourner ce problème en mettant COALESCE(CodeClient, 0) CodeClient et en modifiant mon code Delphi pour qu'il n'y ai jamais de CodeClient à 0.

    Mon 2ème problème, beaucoup plus ennuyeux :
    Lorsque j'effectue ceci :
    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
    queRech:= TADOQuery.Create(nil);
    queRech.Connection := ADOConnection;
    try
      DateTmp:= StrToDateTime('08/04/2009 10:45:00');
      with queRech do
      begin
        Close;
        SQL.Clear;
        SQL.Add('SELECT CodePersonnel');
        SQL.Add('  FROM PLANNINGS');
        SQL.Add(' WHERE DATE_FORMAT(DateHeure, ''%d/%m/%Y %H:%i:%s'') = DATE_FORMAT(:LaDateHeure, ''%d/%m/%Y %H:%i:%s'')');
        Parameters.ParamByName('LaDateHeure').DataType:= ftDateTime;
        Parameters.ParamByName('LaDateHeure').Value:= DateTmp;
        Open;
        if not EOF then
             showmessage('not eof')
        else showmessage('eof');
      end;
    finally
      FreeAndNil(queRech);
    end;
    - Delphi m'affiche eof alors que j'ai bien un enregistrement en base. D'ailleurs si je ne fais pas de restriction sur une date mais sur un entier ou une chaine. Ma requete fonctionne.
    => Que me conseillez-vous ? Je m'en peux plus, je craque

    - Est-ce que le composant ADO de delphi aurait des problème avec la dernière version de MySQL ?
    - Est-ce que le composant possède des bug connus ?
    - Y a t-il une mise à jour à effectuer ? (J'ai mis delphi à jour avec l'update 2)

  2. #2
    Membre éclairé

    Inscrit en
    Février 2005
    Messages
    356
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 356
    Par défaut
    J'ai encore bidouller quelque chose et ça à l'air de fonctionner.

    Voici mon code (Exemple 1) :

    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
    var
      DateTmp1: TDateTime;
      queSup: TAdoQuery;
    begin
      DateTmp1:= StrToDateTime('08/04/2009 10:45:00');
      queSup:= CreeQuery;
      try
        with queSup do
        begin
          Close;
          SQL.Clear;
          SQL.Add('SELECT DateHeure FROM PLANNINGS');
          SQL.Add(' WHERE cast(DateHeure as char) = cast(:LaDateHeure as char)');
          Parameters.ParamByName('LaDateHeure').DataType:= ftString;
          Parameters.ParamByName('LaDateHeure').Value:= FormatDateTime('yyyy-mm-dd hh:mm:ss', DateTmp1);
          Open;
          if not EOF then
                showmessage('not eof')
          else showmessage('eof');
        end;
      finally
        FreeAndNil(queSup);
      end;
    Voici mon code (Exemple 2) :
    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
    var
      DateTmp1,
      DateTmp2: TDateTime;
      queSup: TAdoQuery;
    begin
      DateTmp1:= StrToDateTime('08/04/2009 10:45:00');
      DateTmp2:= StrToDateTime('08/04/2009 11:00:00');
      queSup:= CreeQuery;
      try
        with queSup do
        begin
          Close;
          SQL.Clear;
          SQL.Add('SELECT DateHeure FROM PLANNINGS');
          SQL.Add(' WHERE cast(DateHeure as char) between cast(:LaDateDebut as char) and cast(:LaDateFin as char)');
          Parameters.ParamByName('LaDateDebut').DataType:= ftString;
          Parameters.ParamByName('LaDateDebut').Value:= FormatDateTime('yyyy-mm-dd hh:mm:ss', DateTmp1);
          Parameters.ParamByName('LaDateFin').DataType:= ftString;
          Parameters.ParamByName('LaDateFin').Value:= FormatDateTime('yyyy-mm-dd hh:mm:ss', DateTmp2);
          Open;
          while not EOF do
          begin
            showmessage(FieldByName('DateHeure').AsString);
            Next;
          end;
          showmessage('eof');
        end;
      finally
        FreeAndNil(queSup);
      end;
    => Ici, la requete me retourne bien 2 lignes. Une ligne à '08/04/2009 10:45:00' et une autre à '08/04/2009 11:00:00' (donnée enregistré en base)
    ==> J'en conclue que le Between fonctionne correctement même si je cast en chaine (Ce que je n'étais pas sûr)

    C'est tout de même étrange ce bidoullage. Avez-vous une explication ou une meilleure solution ?

  3. #3
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Par défaut
    Salut pepito,

    Pour ton 1ere probleme apparement tu as trouvé.
    (en fait explique moi le COALESCE, peutêtre qu'on peu le contourner par un where ?)

    Pour le deuxieme probleme, je pige pas le DATE_FORMAT peux-être en nous indiquant le type de base que tu utilise se serais plus claire.
    Pour ma part (sur une base MDB) je fais cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
          SQL.Clear;
          SQL.Add('SELECT DateHeure FROM PLANNINGS');
          SQL.Add(' WHERE DateHeure=: xDate ');
          Parameters.ParamByName('xDate').Value:= FormatDateTime('dd/mm/yyyy hh:mm:ss', DateTmp1);
          Open;
    Evidement DateTmp1 doit être du même type, de plus le dd/mm/yyyy hh:mm:ss il faudrait tester mm/dd/yyyy hh:mm:ss également car entre Français et anglais sa peut bcp jouer. J'utilise plutot les / comme séparateur de date c'est plus logique mais à toi de voir.

    a plus

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 658
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 658
    Billets dans le blog
    65
    Par défaut
    Franchement MySQL et ADO je maitrise pas vraiment mais ce que je ne comprends c'est pourquoi vous voulez absolument passer les dates en temps que chaine de caractères , surtout que vous les passez en paramètres .

    Laissez donc le compo et la base faire leur travail

    pour reprendre l'exemple de BuzzLeclaire (un petit au passage)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
          SQL.Clear;
          SQL.Add('SELECT DateHeure FROM PLANNINGS');
          SQL.Add(' WHERE DateHeure=: xDate ');
          Parameters.ParamByName('xDate').Value:= DateTmp1;
          Open;
    ceci devrait fonctionner et évite d'avoir a jouer entre les différentes représentations des dates

    idem pour un between entre deux dates
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SQL.Add('SELECT DateHeure FROM PLANNINGS');
    SQL.Add(' WHERE DateHeure between :LaDateDebut  and :LaDateFin');
    Parameters.ParamByName('LaDateDebut').Value:=  DateTmp1;
    Parameters.ParamByName('LaDateFin').Value:= DateTmp2;
    ceci devrait fonctionner , au pire en indiquant que le datatype est TDateTime (ADO et moi égal 2 )

    enfin ceci fonctionne parfaitement avec Firebird et des composants tels que ZEOSDBO,IBxxxx,DBXPRESS,FIBPlus etc ..... (ADO je n'ai pas testé cf +haut )

  5. #5
    Membre éclairé

    Inscrit en
    Février 2005
    Messages
    356
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 356
    Par défaut
    Alors pour répondre à vos questions...

    Pour ton 1ere probleme apparement tu as trouvé.
    (en fait explique moi le COALESCE, peutêtre qu'on peu le contourner par un where ?)
    COALESCE est équivalent au NVL côté Oracle. Il permet de mettre une valeur par défaut (le 2eme paramètre) lorsque ton 1er paramètre vaut NULL.

    Pour le deuxieme probleme, je pige pas le DATE_FORMAT peux-être en nous indiquant le type de base que tu utilise se serais plus claire.
    Pour ma part (sur une base MDB) je fais cela :
    C'est une bdd MySQL v5.1.33, moteur InnoDB (je sais pas si ya mieux...)

    Sinon au départ, javais essayé d'effectuer une requête simple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SQL.Clear;
          SQL.Add('SELECT DateHeure FROM PLANNINGS');
          SQL.Add(' WHERE DateHeure= :LaDateHeure');
          Parameters.ParamByName('LaDateHeure').DataType:= ftDateTime;
          Parameters.ParamByName('LaDateHeure').Value:= DateTmp1;
          Open;
    Mais ceci ne fonctionne pas (Ma requête me retournait aucun résultat). C'est pourquoi j'ai posté sur ce forum.
    Ensuite, je me suis dit, je vais blinder la requête car c'est peut-être un problème de format de date. Du coup, j'ai spécifier un format de chaque côté pour comparer la même chose.
    Idem, ça ne fonctionne pas. (aucun résultat)

    Du coup, j'ai essayé encore autre chose et c'est la où j'ai pensé à convertir ma date en chaine. Et la, ça fonctionne.

    Concernant SergioMaster, Je sais bien qu'il est 100fois mieux de passer une date qu'une chaine. Mais ça ne fonctionnait pas

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ceci devrait fonctionner , au pire en indiquant que le datatype est TDateTime (ADO et moi égal 2 )
    C'est ce dont j'ai fait. Voir mon 1er post.

    La, je viens d'essayer quelque chose de beaucoup plus cohérent (la nuit porte conseil...)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SQL.Add('SELECT DateHeure');
          SQL.Add('  FROM PLANNINGS');
          SQL.Add(' WHERE DateHeure = :LaDateDebut');
          Parameters.ParamByName('LaDateDebut').Value:= FormatDateTime('yyyy-mm-dd hh:mm:ss', DateTmp1);
    Ceci fonctionne également. Ca m'embete un peu car FormatDateTime renvoit une chaine et non une date sous le format 'yyyy-mm-dd hh:mm:ss' mais bon...C'est déjà bcp plus lisible.

    J'avais essayé de faire ceci mais ça ne fonctionne pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SQL.Add('SELECT DateHeure');
          SQL.Add('  FROM PLANNINGS');
          SQL.Add(' WHERE DateHeure = DATE_FORMAT(:LaDateDebut, ''%Y-%m-%d %H:%i:%s'')');
          Parameters.ParamByName('LaDateDebut').DataType:= ftDateTime;
          Parameters.ParamByName('LaDateDebut').Value:= DateTmp1;
    Voilà, je pense que je vais resté sur la dernière solution...
    Et sinon voilà pourquoi j'insiste sur le format de la date.
    http://dev.mysql.com/doc/refman/5.0/...functions.html
    http://dev.mysql.com/doc/refman/5.0/fr/datetime.html
    Le type DATETIME est prévu lorsque vous souhaitez stocker une date et une heure. MySQL affiche les valeurs de type DATETIME au format ‘AAAA-MM-JJ HH:MM:SS’.

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

Discussions similaires

  1. Problème concaténation requête avec ORACLE
    Par kobe dans le forum Bases de données
    Réponses: 2
    Dernier message: 16/08/2005, 11h57
  2. recuperer une requête avec le composant TIBSQL ??
    Par vbcasimir dans le forum Bases de données
    Réponses: 11
    Dernier message: 31/05/2005, 12h05
  3. Réponses: 3
    Dernier message: 11/10/2004, 17h26
  4. problème de requête avec jointures
    Par tinhat dans le forum Requêtes
    Réponses: 7
    Dernier message: 11/08/2003, 10h33
  5. Problème dans requête avec count()
    Par BadFox dans le forum Requêtes
    Réponses: 3
    Dernier message: 08/07/2003, 18h02

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