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

Lazarus Pascal Discussion :

TSQLQuery : filtrer sur champ calculé par iif() dans select [Lazarus]


Sujet :

Lazarus Pascal

  1. #1
    Membre averti
    Homme Profil pro
    Formateur en informatique
    Inscrit en
    Janvier 2007
    Messages
    1 144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Formateur en informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 144
    Points : 337
    Points
    337
    Par défaut TSQLQuery : filtrer sur champ calculé par iif() dans select
    Bonjour,

    Je souhaite filtrer sur mon TSQLQuery. Je n'ai pas de problème pour le faire sur tous mes autres champs, mais j'ai un champ qui est calculé lors du select, et ce champ-là ne me permet pas de filtrer dessus.

    Voici ma requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Select Nom, Prenom, iif(ChampTest<TestChamp, 'Super', 'Pas cool') as Statut From MyTable
    J'utilise une base Firebird.
    Si je filtre sur Statut = Super, je n'ai aucune ligne alors que je vois bien qu'il y a des lignes dans mon tableau...
    Le filtre fonctionne pour tous les autres champs. Je pense que le souci vient du champ calculé...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        IBQuery1.Filtered:=False;
        IBQuery1.Filter:= 'Statut = ' + QuotedStr('Super');
        IBQuery1.Filtered:=True;
    Comment contourner ce problème ?

    Merci d'avance,

  2. #2
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Salut je ne suis pas un pro des BDD

    Pourquoi vouloir passer par un filtre pour une requête si simple ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SQLCommand :=  'select Nom, Prenom where Statut = ' + iif(ChampTest<TestChamp, 'Super', 'Pas cool')+' From MyTable';
    Par contre je ne me souviens plus si il faut "quoter" les valeurs (Super, Pacool) ce qui donnerait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    QuoteStr(iif(ChampTest<TestChamp, 'Super', 'Pas cool'));
    En plus j'ai un doute sur la construction de ta commande SQL parce que le résultat donnerait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Select Nom, Prenom, Super as Statut From MyTable
    Vraiment pas sûr de la validité de cette commande.

    Sinon vu que tu "filtres" à mon sens, j'aurais plutôt fais comme ceci : (comme je l'ai dit, je suis pas un pro avec les BDD et Lazarus, c'est donc peut-être faux) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        SQLCommand :=  'select Nom, Prenom From MyTable';
     
        IBQuery1.Filtered:=False;
        IBQuery1.Filter:= 'Statut = ' + QuotedStr iif(ChampTest<TestChamp, 'Super', 'Pas cool'));
        IBQuery1.Filtered:=True;
    J'ai également trouvé cette discussion : https://www.developpez.net/forums/d1...ery-numerique/ qui pourrait t'aider.

    A+
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  3. #3
    Membre averti
    Homme Profil pro
    Formateur en informatique
    Inscrit en
    Janvier 2007
    Messages
    1 144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Formateur en informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 144
    Points : 337
    Points
    337
    Par défaut
    Bonjour,

    Effectivement, soit on ne s'est pas compris, soit ta réponse est fausse...
    J'utilise les bases de données depuis des années (Access, mysql, firebird), et il est tout a fait possible de calculer un critère dans un select de la manière suivante :
    Par exemple, une requête qui détermine en fonction de la date de naissance, si l'utilisateur est mineur ou adulte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Select Nom, Prenom, iif(Cast('Now' as date)-DateNaissance<18, 'Mineur', 'Adulte') as StatutAge from TableUsers
    Cette requête permettrait d'afficher dans un dbgrid tous les utilisateurs de la table TableUsers avec le Nom, Prenom et le StatutAge qui serait "Mineur" ou "Adulte".
    La difficulté est maintenant d'utiliser la propriété filter du TSQLQuery pour filtrer sur cette requête...

    Alors bien évidement, si je test en direct sur ma base de donnée et que je filtre avec un Where, je ne peux pas le faire directement sur la requête principale. Je dois faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Select * from (Select Nom, Prenom, iif(Cast('Now' as date)-DateNaissance<18, 'Mineur', 'Adulte') as StatutAge from TableUsers) Where StatutAge = 'Mineur'
    Cette requête fonctionne en direct sur la base.

    Si je l'applique dans Lazarus sans le Where donc juste avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Select * from (Select Nom, Prenom, iif(Cast('Now' as date)-DateNaissance<18, 'Mineur', 'Adulte') as StatutAge from TableUsers)
    Le filtre sur StatutAge ne fonctionne pas.

    Je pense qu'il faudrait peut être que le champ soit calculé directement depuis la base, mais je ne trouve rien là dessus. Si quelqu'un avait une piste je suis preneur.

    Merci d'avance,

  4. #4
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Ok je n'avais pas bien compris effectivement.

    Je me pose quelques questions. Est-ce que ce champ 'Status' doit-il être déclaré pour être exploité ? Le champ 'Status' est-il déclaré dans le SQLQuery (clic Droit editeur de champs) ou l'initialises tu à la main ?

    Une discussion sous Delphi qui se rapproche https://www.developpez.net/forums/d1...champ-calcule/

    Sinon peut-être utiliser l'événement OnCalcField et activer le filtre dedans. mais à mon avis il faut passer par l'événement OnFilterRecord pour faire ce que tu souhaites
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  5. #5
    Membre averti
    Homme Profil pro
    Formateur en informatique
    Inscrit en
    Janvier 2007
    Messages
    1 144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Formateur en informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 144
    Points : 337
    Points
    337
    Par défaut
    Salut,
    Je créer tous les composants à la main donc je n'ai pas de TSQLQuery sur mon form. Je fais tout dans le code.
    Je creuse pour l'instant du côté de la base de données, en créant une vue dans la base, mais ça ne veut toujours pas fonctionner sous lazarus alors qu'en SQL direct sur la base je n'ai pas de problème...

    Sinon j'ai une solution de bourrin qui n'est pas optimisée, ça serait de relancer une nouvelle requete avec un Where, mais j'aimerai pouvoir filtrer sur la query déjà ouverte...

  6. #6
    Membre averti
    Homme Profil pro
    Formateur en informatique
    Inscrit en
    Janvier 2007
    Messages
    1 144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Formateur en informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 144
    Points : 337
    Points
    337
    Par défaut
    Bonsoir,
    J'ai résolu tous mes problème en utilisant IBX4Lazarus. J'utilisais ce composant par le passé parce que lazarus n'avait pas de prise en charge pour les bases Firebird. Depuis quelques temps, j'utilise les composants standard de lazarus pour me connecter à firebird. Je constatais souvent des incohérences dans l'execution des requêtes.

    Avec ce composant sur mesure pour Interbase/firebird, je n'ai plus de problème !!!
    De plus, comme tous mes composants étaient créés dynamiquement, je n'ai eu que 2 minutes d'adaptation ! Comme quoi, ça a du bon de se faire mal dès le début d'un programme !

    Pour telecharger cette bibliothèque : http://www.mwasoftware.co.uk

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    245
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 245
    Points : 534
    Points
    534
    Par défaut
    Bonsoir,

    Un exemple pour utiliser les filtres avec un TSQLQuery:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        MonSQLQuery.FilterOptions:=MonSQLQuery.FilterOptions-[foCaseInsensitive];
        MonSQLQuery.Filter:='nom_conjoint=''TRUC*'' or nom=''MACHIN''';
        MonSQLQuery.Filtered:=True;
    FilterOptions=[foCaseInsensitive,foNoPartialCompare] par défaut.
    foNoPartialCompare permet en mettant * à la fin de TRUC de trouver les nom_conjoint commençant par TRUC.
    Le filtrage intervient sur les résultats de la requête, donc indépendamment du texte de cette requête.

    Mais comme beaucoup je préfère utiliser le filtrage dans la requête, et il n'existe pas que les TSQLQuery et les IBX pour les bases Firebird. Il y a aussi les ZEOS et les UIB.

    André

    PS: Dans vos exemples, ça m'étonnerai que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    iif(Cast('Now' as date)-DateNaissance<18, 'Mineur', 'Adulte') as StatutAge
    donne satisfaction puisque Cast('Now' as date)-DateNaissance retourne un nombre de jours.
    Par contre avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    select iif(cast('today' as date)>=dateadd(18 year to cast('12 19 1945' as date)),'Majeur','Mineur')
     from rdb$database
    je suis rassuré d'apprendre que je suis majeur

  8. #8
    Membre éclairé
    Avatar de FOCUS77
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2014
    Messages
    336
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2014
    Messages : 336
    Points : 680
    Points
    680
    Par défaut
    Bonjour à tous

    @ jojo86

    j'ai refais ton exemple dans les mêmes conditions et le code a fonctionnait convenablement

    à condition que:

    Le Sise du champ 'Statut' doit être égal à la longueur de la chaîne 'Super' soit 5.

    mais l’inconvénient est que la deuxième chaîne 'Pas cool' ne va pas marcher car

    sa longueur dépasse 5.

    Afin de remédier à ce problème on va fixer le sise à 10.

    et le code devient:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    procedure TF_MAINFORM.Button2Click(Sender: TObject);
    begin
    MDT.SqlQuery.Filtered:=False;
    MDT.SqlQuery.Filter:='Statut='+ QuotedStr('pas*');
    MDT.SqlQuery.Filtered:=True
    end;

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

Discussions similaires

  1. [AC-2010] Champ calculé par défaut dans sous formulaire
    Par Klyslane dans le forum IHM
    Réponses: 2
    Dernier message: 18/01/2014, 18h48
  2. Réponses: 2
    Dernier message: 19/11/2011, 13h21
  3. somme sur champ calculé et table liée
    Par pierrot67 dans le forum Bases de données
    Réponses: 6
    Dernier message: 06/11/2006, 18h02
  4. [Access] Calcule par ligne dans une requête
    Par Belze dans le forum Langage SQL
    Réponses: 2
    Dernier message: 13/02/2006, 09h09
  5. Recherche sur champ calculé
    Par srvremi dans le forum Bases de données
    Réponses: 5
    Dernier message: 06/07/2004, 14h04

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