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 :

ORACLE même SQL lancé via BDE ou ODA = DataSet différent


Sujet :

Bases de données Delphi

  1. #1
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 447
    Points : 24 849
    Points
    24 849
    Par défaut ORACLE même SQL lancé via BDE ou ODA = DataSet différent
    Voilà j'ai une requête,
    et bien, via
    BDE = OK
    Explorateur SQL = OK
    SQL*PLUS = OK
    mais en ADO, le résultat est différent :
    - Les Record avec CDateReceip à null sont ignorés comme si le null était plus fort que le OR avec CDateEstimate
    - Les Record avec CDateReceip avec une date en dehors du filtre, idem sont ignorés, ... pour la date rentre dans le OR avec CDateEstimate

    Une sorte d'optimisation des requêtes chez ADO qui foire totalement ?
    Comment désactiver cette optimisation ?


    voici la requête, j'ai juste mis * dans la liste de champs sinon c'est trop long
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT *
    FROM TPAYMENT TPA 
    INNER JOIN TCONTRAC TC on (TPA.CContractID=TC.CContractId)
    INNER JOIN TCOUNTRY TCO on (TC.CCountryId=TCO.CCountryId)
    INNER JOIN TDONOR TD on (TC.CDonorId=TD.CDonorId)
    INNER JOIN TCURREN TCU on (TC.CCurrencyId=TCU.CCurrencyId)
    WHERE TPA.CPayID > 0
    AND (TC.CCountryId IN (52))
    AND (((TPA.CDateReceip >= :DDateBegin) AND (TPA.CDateReceip <= :DDateEnd)) OR ((TPA.CDateEstimate >= :DDateBegin) AND (TPA.CDateEstimate <= :DDateEnd)))
    ORDER BY TCO.CCountryName,
    TD.CDonorName,
    TC.CContractCode
    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
    (
    	(
    		(
    			TPA.CDateReceip >= :DDateBegin
    		)
    		AND
    		(
    			TPA.CDateReceip <= :DDateEnd
    		)
    	)
    	OR
    	(
    		(
    			TPA.CDateEstimate >= :DDateBegin
    		)
    		AND
    		(
    			TPA.CDateEstimate <= :DDateEnd
    		)
    	)
    )
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  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
    Pourquoi n'utilises tu pas between, qui est fait exactement pour ce que tu veux faire.

    Sinon, TC.CCountryId IN (52) a modifier en TC.CCountryId = 52, il est inutile de faire faire des calculs supplèmentaires à la requetes pour 1 valeur.

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    SELECT *
    FROM TPAYMENT TPA 
    INNER JOIN TCONTRAC TC on (TPA.CContractID=TC.CContractId)
    INNER JOIN TCOUNTRY TCO on (TC.CCountryId=TCO.CCountryId)
    INNER JOIN TDONOR TD on (TC.CDonorId=TD.CDonorId)
    INNER JOIN TCURREN TCU on (TC.CCurrencyId=TCU.CCurrencyId)
    WHERE TPA.CPayID > 0
    AND (TC.CCountryId IN (52))
    AND ((TPA.CDateReceip between :DDateBegin AND :DDateEnd) OR (TPA.CDateEstimate between :DDateBegin AND :DDateEnd))
    ORDER BY TCO.CCountryName,
    TD.CDonorName,
    TC.CContractCode

    De plus avec Ado (je crois que c'est pareil avec le BDE), mettre le même paramètre ne sera pas rensigné la deuxieme fois. c'est peut être de la que viens ton problème.
    Le premier DDateBegin sera renseigné, mais pas le 2em (idem pour DDateEnd)
    Modérateur Delphi

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

  3. #3
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 447
    Points : 24 849
    Points
    24 849
    Par défaut
    Merci Rayek de ta réponse,

    - la requête cité est la requête finale, mais n'est qu'un exemple, le IN est indispensable que cela peut-être une liste de plusieurs pays, mais pour mon test, j'ai pris un cas simple avec un seul pays, mais bonne remarque si l'on ne connait pas le contexte ...

    - Pour le between, j'y avais pensé, mais les bornes début et fin, ne sont pas obligatoires (parfois aucune, parfois l'une des deux, parfois les deux ... requêtes construites selon options), et comme c'est une application que nous n'avons pas développé à l'origine mais que nous avons porté de Paradox vers Oracle, déjà que nous sommes hors temps, je dois me limiter à la plus petite quantité de modification (je n'ai pas envie de me palucher des condition pour mettre un <= => ou un between pour l'ensemble des critères possibles, le code étant très redondant pour chaque valeur testé, là je n'en ai cité que deux), mais je ne pense pas que cela soit la cause du problème

    - Ta remarque sur les paramètres est très intéressante, ... il est vrai que j'ai testé la requête paramêtré via le BDE comme ceci (voir code, à noter que ParamCount renvoie 4 et non 2), mais cette requête au sein de l'application réelle en Paradox fonctionne parfaitement, mais c'est une piste qu'un problème de paramètres répètés (mal géré par ADO) soit la cause d'un False permanent pour le deuxième test ... le problème c'est que dans le code, les valeurs viennent non pas d'un ParamByName mais d'un enchainement via DataSource d'un autre DataSet qui contient les colonnes 'DDateBegin' et 'DDateEnd' mais pour cette requête (la seule pour le moment, mais vu le nombre d'option qui existe dans l'editeur de rapport, d'autres conditions avec paramètres répètés vont un jour survenir), donc pour cette requête, un remplissage manuel (sans DataSource) est à tenté ! Dès que j'ai du temps affecté sur ce projet, je te donne une réponse ...

    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
    procedure TTableViewerForm.BtnExecuteSQLClick(Sender: TObject);
    var
      I: Integer;
      Value: string;
    begin
      QueryTest.SQL.Assign(MemoSQL.Lines);
      QueryTest.DataBaseName := EdDataBaseName.Text;
      QueryTest.Prepare();
      for I := 0 to QueryTest.ParamCount - 1 do
      begin
        Value := '';
        if InputQuery('Execute Params', QueryTest.Params[I].Name, Value) then
        begin
          case  QueryTest.Params[I].Name[1] of
            'S' : QueryTest.Params[I].AsString := Value;
            'B' : QueryTest.Params[I].AsBoolean := StrToBool(Value);
            'D' : QueryTest.Params[I].AsDateTime := StrToDateTime(Value);
            'I' : QueryTest.Params[I].AsInteger := StrToInt(Value);
            'F' : QueryTest.Params[I].AsFloat := StrToFloat(Value);
          end;
        end
        else
          Exit;
      end;
     
      DataSourceTest.DataSet := QueryTest;
      QueryTest.Open();
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 447
    Points : 24 849
    Points
    24 849
    Par défaut
    J'avais fait une rustine, en utilisant une TQuery pour cette requête au lieu d'une TADOQuery, et cela fonctionnait parfaitement, malgré la répétition du paramètre ...

    Mais cette modification oblige d'avoir le BDE, le client voulant s'en débarasser, j'ai donc retirer ce lien avec la table Master (les options du filtre sont stockés dans une table, véritable usine à gaz au lieu de définir à la main les paramètres, cela m'aurait évité ces soucis !), en remplissant moi-même les paramètres comme le fait la fonction TQuery.SetParamsFromCursor et non comme TADOQuery.SetParamsFromCursor, cela fonctionne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
       DataLinkDataSource := DetailDataSet.DataSource;
       DetailDataSet.DataSource := nil;
       if DataLinkDataSource <> nil then
       begin
         DataSet := DataLinkDataSource.DataSet as TCustomADODataSet;
         if DataSet <> nil then
           for I := 0 to DetailDataSet.Parameters.Count - 1 do
             with DetailDataSet.Parameters.Items[I] do
               Assign(DataSet.FieldByName(Name));
       end;
    J'ai facilement trouvé TQuery.SetQueryParams, ou l'on voit que les paramètres sont exploités par index, mais je n'ai pas trouvé ce code dans TADOQuery car c'est géré via une Interface ...

    Si c'est pas un bug de la lib ADO ... si les paramètres ne peuvent pas être répété, cela devrait lever une exception, alors que la cela passe avec un comportement abhérant ...

    Merci Rayek
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

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

Discussions similaires

  1. Résultat tronqué lors d'une requête SQL via BDE
    Par Jami68100 dans le forum DB2
    Réponses: 0
    Dernier message: 07/12/2012, 14h37
  2. Réponses: 0
    Dernier message: 25/08/2010, 13h19
  3. administrer sql server via oracle enterprise manager
    Par doudi14 dans le forum Administration
    Réponses: 1
    Dernier message: 09/07/2008, 13h12
  4. PHP + Oracle + PL/ SQL
    Par bchristo dans le forum SQL
    Réponses: 12
    Dernier message: 28/04/2004, 15h49

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