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

 Delphi Discussion :

Delphi 7: requête sql BDE


Sujet :

Delphi

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Directeur technique
    Inscrit en
    mars 2018
    Messages
    56
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : Service public

    Informations forums :
    Inscription : mars 2018
    Messages : 56
    Points : 25
    Points
    25
    Par défaut Delphi 7: requête sql BDE
    Bonjour tout le monde,
    je reviens vers vous concernant un ancien projet développé en D7 avec une base de données paradox donc en BDE,
    j'ai été contraint de revenir dessus!

    C'est un programme pour la gestion des abonnements pour un client.
    Il y a deux tables Abonne(Id_ab, nom_ab, prenom_ab...etc) et Abonnement(Id_abm, dateD_abm, dateF_abm, validite_abm(true/false)...Id_ab) et aussi et bien sur d'autres tables...lol.

    >Explication:

    Chaque abonné ne peut avoir qu'un seul abonnement en cours de validité, mais les anciens abonnements restent dans la base de données et le champ validite_abm reçoit false cela se passe lors de l'exécution de l'application par un code qui vérifie les dates des abonnements par rapport à la date actuelle dans l’événement OnCreate de la forme principale...jusque-là tout est OK

    >Mon problème:

    Besoin de votre aide pour élaborer une requête sql afin d'afficher les abonnés qui n'ont pas d'abonnement en cour de validité.
    Je vous rappelle que l'abonné peut avoir un abonnement en cour de validité et aussi au même temps d'anciens abonnements qui ne sont plus Valides (validite_abm=false);
    autrement dit si je fais un " select .......where abonement.validite_abm=false"
    cela m'affiche certes les abonnements expirés mais ceux qui ont un abonnement en cours de validité se voient affichés dans la liste des abonnés non autorisé d'accès vu ses anciens abonnements !!!

  2. #2
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique
    Inscrit en
    janvier 2007
    Messages
    11 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : janvier 2007
    Messages : 11 013
    Points : 28 009
    Points
    28 009
    Billets dans le blog
    27
    Par défaut
    Bonjour,

    mais les anciens abonnements restent dans la base de données et le champ validite_abm reçoit false cela se passe lors de l'exécution de l'application par un code qui vérifie les dates des abonnements par rapport à la date actuelle dans l’événement OnCreate de la forme principale...jusque-là tout est OK
    bof ! Ce n'est pas vraiment ce que je qualifierai très carré mais j'ai retrouvé cette conversation qui déjà en faisait état. Puis qu'il y a les colonnes dateD_abm, dateF_abm obtenir les abonnements en cours par rapport à la date du jour doit pouvoir s'obtenir par le SQL
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT id_abm, dateD_abm, dateF_abm, id_ab FROM  Abonnement WHERE :NOW>= dateD_abm AND :NOW<=dateF_abm
    Obtenir les abonnés (une seule fois) n'ayant aucun abonnement en cours devrait pouvoir s'obtenir en utilisant une technique que l'on nomme dans les SGBDs modernes : une CTE. Avec Paradox, il est possible d'utiliser un texte SQL comme une table donc si le précédent SQL est enregistré au même endroit que les tables il doit être possible de faire une jointure entre les abonnements "actifs" et la table des abonnements

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT A.id_ab,S.id_ABM AS ABENCOURS FROM Abonnement A LEFT JOIN ABONNEMENTENCOURS.SQL S ON A.id_ab=S.id_ab
    n'obtenir que les abonnements des utilisateurs sans abonnements actifs se fera en ajoutant la clause WHERE ABENCOURS IS NULLà partir de la même technique (enregistrement du texte SQL en ABENCOURS.SQL)

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT DISTINCT(id_ab) FROM ABENCOURS.SQL WHERE ABENCOURS IS NULL
    vous obtiendrez les utilisateurs qui n'ont aucun abonnement en cours

    Il y a certainement mieux le dernier SQL est certainement évitable
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT DISTINCT A.id_ab,S.id_ABM AS ABENCOURS FROM Abonnement A LEFT JOIN ABONNEMENTENCOURS.SQL S ON A.id_ab=S.id_ab WHERE ABENCOURS IS NULL

    P.S. La syntaxe est approximative il manque peut-être des guillemets " " pour l'utilisation des textes SQL, écrit de mémoire et sans jeu d'essai difficile d'en être sûr
    La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein

    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Tokyo, Rio) et peut être quelques autres
    SGBD : Firebird 2.5, 3, SQLite
    générateurs Etats : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Ubuntu, Androïd

  3. #3
    Membre habitué
    Homme Profil pro
    Consultant fonctionnel
    Inscrit en
    décembre 2014
    Messages
    86
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Consultant fonctionnel

    Informations forums :
    Inscription : décembre 2014
    Messages : 86
    Points : 193
    Points
    193
    Par défaut
    Bonsoir,
    Vous faîtes bien compliqué.
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    select * from Abonne a
    where a.Id_ab not in (select b.Id_Ab from Abonnement b where b.validite_abn=true)
    Tous les abonnés dont l'Id n'est pas dans les Abonnements valides.
    (testé seulement avec Db2, à vérifier avec d'autres DB)
    solilog

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique
    Inscrit en
    janvier 2007
    Messages
    11 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : janvier 2007
    Messages : 11 013
    Points : 28 009
    Points
    28 009
    Billets dans le blog
    27
    Par défaut
    Citation Envoyé par solilog Voir le message
    Vous faites bien compliqué.
    Oui mais je n'aime pas les WHERE IN ( ) et je doute de la fiabilité du processus de mise à jour de validite_abn
    La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein

    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Tokyo, Rio) et peut être quelques autres
    SGBD : Firebird 2.5, 3, SQLite
    générateurs Etats : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Ubuntu, Androïd

  5. #5
    Membre habitué
    Homme Profil pro
    Consultant fonctionnel
    Inscrit en
    décembre 2014
    Messages
    86
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Consultant fonctionnel

    Informations forums :
    Inscription : décembre 2014
    Messages : 86
    Points : 193
    Points
    193
    Par défaut
    Bonjour,
    Vous n'aimez pas (bizarre) mais c'est la seule façon simple et concise de faire, et c'est rapide. On peut aussi utiliser le "not exists" faire
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    select * from Abonné a where not exists (select b.Id_Ab from Abonnement where a:Id_Ab=b.Ib_ab and b.Validite_abn=true)
    mais je préfère le not in du 1er exemple.

    solilog

  6. #6
    Membre chevronné
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    mars 2006
    Messages
    1 131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : mars 2006
    Messages : 1 131
    Points : 2 036
    Points
    2 036
    Billets dans le blog
    5
    Par défaut
    Attention le SQL de Paradox n'est pas un SQL Standard. Le type de requête de Paradox est le QBE

  7. #7
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique
    Inscrit en
    janvier 2007
    Messages
    11 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : janvier 2007
    Messages : 11 013
    Points : 28 009
    Points
    28 009
    Billets dans le blog
    27
    Par défaut
    re,

    Le SQL Local terme que je préfère à QBE qui pour moi fait plus référence à l'utilitaire de création de requête par l'exemple (Query By Exemple) est très limité

    J'ai eu des doutes concernant WHERE EXISTS mais j'ai pu retrouver ce site http://www.nknabe.dk/localsql/index.html j'adhère donc plus à cette seconde proposition
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    select * from Abonne a where not exists (select b.Id_Ab from Abonnement where a:Id_Ab=b.Ib_ab and b.Validite_abn=true)
    en remplaçant la colonne Validit_abn par un travail sur les dates (on ne se refait pas)
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    select * from Abonne a where not exists (select b.Id_Ab from Abonnement where a:Id_Ab=b.Ib_ab and dateD_abm>=:now AND dateD_ab=:NOW)
    Je me demande même si la syntaxe
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    select * from Abonne a OUTER JOIN (select b.Id_Ab from Abonnement where dateD_abm>=:now AND dateD_ab=:NOW) b ON (a.id_ab=b.Ib_ab)
    serait acceptée mais bon, sans jeu d'essai je ne vais pas m'y prendre le chou
    La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein

    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Tokyo, Rio) et peut être quelques autres
    SGBD : Firebird 2.5, 3, SQLite
    générateurs Etats : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Ubuntu, Androïd

  8. #8
    Membre chevronné
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    mars 2006
    Messages
    1 131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : mars 2006
    Messages : 1 131
    Points : 2 036
    Points
    2 036
    Billets dans le blog
    5
    Par défaut
    Non je parlais du QBE qui est une transcription en Delphi du QBE de l'outil Paradox et est bien plus puissant que le SQL pour ce type de
    base. J'ai mis en pièce jointe l'unité QBE.PAS qbe.pas
    Exemple :

    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
     
    var
      QBE1: TQBE;
      Tb1 : TTable ;
      iNbre1,iNbre2 : integer ;
      stTypeTraitement : string ;
      bOk : Boolean ;
      sr1 : TSearchRec;
    begin
      QBE1 := TQBE.Create (nil) ;
      QBE1.RequestLive := False ;
      QBE1.BlankasZero := False ;
      QBE1.AuxTables := False ;
      QBE1.AnswerType := ttParadox ;
      Tb1 := TTable.Create (nil) ;
      Tb1.DatabaseName := 'MABASE' ;
      QBE1.QBE.text :=
          'Query ¦'+
          '¦'+
          'Import.DB | IDLOT                         |¦'+
          '			     | Check calc count all as Nbre2 |¦'+
          '¦'+
          'EndQuery';
      QBE1.AnswerTable := ':MABASE:T1.DB' ;
      QBE1.open ;

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    avril 2010
    Messages
    190
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : avril 2010
    Messages : 190
    Points : 426
    Points
    426
    Par défaut
    Bonjour,
    Citation Envoyé par SergioMaster Voir le message
    je doute de la fiabilité du processus de mise à jour de validite_abn
    Tout à fait d'accord avec Sergio lorsque je lis ça:
    Citation Envoyé par lotfi.lahcene Voir le message
    Chaque abonné ne peut avoir qu'un seul abonnement en cours de validité, mais les anciens abonnements restent dans la base de données et le champ validite_abm reçoit false cela se passe lors de l'exécution de l'application par un code qui vérifie les dates des abonnements par rapport à la date actuelle dans l’événement OnCreate de la forme principale...jusque-là tout est OK
    On ne peut être sûr que de la validité de l'abonnement de l'abonné sélectionné, ou lofti.lahcene devrait nous donner des détails sur le code.

    André

  10. #10
    Membre chevronné
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    mars 2006
    Messages
    1 131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : mars 2006
    Messages : 1 131
    Points : 2 036
    Points
    2 036
    Billets dans le blog
    5
    Par défaut
    Finalement c'est simple : tu interroge la table abonnement (select distinct) tu comptes le nombre de validite_abm par abonné et tu "calc" le max de validite_abm
    Les non abonnés ont un nombre à 1 et max à false. Si tu veux je t'envoie l'exemple

  11. #11
    Nouveau membre du Club
    Homme Profil pro
    Directeur technique
    Inscrit en
    mars 2018
    Messages
    56
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : Service public

    Informations forums :
    Inscription : mars 2018
    Messages : 56
    Points : 25
    Points
    25
    Par défaut
    Bsr à tous,
    en fin de compte j'ai opter pour la solution la plus rapide et facile vu l'urgence
    SQL :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select a.nom_ab, a.prenom_ab, a.photo_ab from abonne a where not exists ( select b.num_ab, b.validite_abm from abonnement b where a.num_ab=b.num_ab and b.validite_abm=true)
    mais j'irai volontiers explorer la solution qu'a proposé @SergioMaster

    Obtenir les abonnés (une seule fois) n'ayant aucun abonnement en cours devrait pouvoir s'obtenir en utilisant une technique que l'on nomme dans les SGBDs modernes : une CTE. Avec Paradox, il est possible d'utiliser un texte SQL comme une table donc si le précédent SQL est enregistré au même endroit que les tables il doit être possible de faire une jointure entre les abonnements "actifs" et la table des abonnements
    mais pour ce qui à été dit concernant la fiabilité du processus de mise à jour de validité_abm ma réponse est : "ça fonctionne bien jusque là"

    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
    procedure TForm3.FormCreate(Sender: TObject);
    begin
    tableabm.Open;
    while not tableabm.Eof do
     begin
      if (TableabmDated_abm.Value<=date)and(TableabmDatef_abm.Value>=date) then
       begin
        tableabm.Edit;
        TableabmValidite_abm.Value:=true;
        tableabm.Post;
        tableabm.FlushBuffers;
       end
     else
      begin
       tableabm.Edit;
       TableabmValidite_abm.Value:=false;
       tableabm.Post;
       tableabm.FlushBuffers;
      end;
      tableabm.Next;
     end;
    tableabm.Close;
    KeyPreview:=true;\\hors contexte 
    end;
    SergioMaster serte le champ validite_abm peut etre evité car on peut traité les dates directement mais vu que lors de ce projet je n'utilisait pas bcp le SQL...

    Merci à tous

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

Discussions similaires

  1. rendre code Delphi en requête SQL
    Par wiski08000 dans le forum Débuter
    Réponses: 15
    Dernier message: 30/10/2018, 11h56
  2. Delphi et requêtes SQL Server 2012
    Par vnans dans le forum Delphi
    Réponses: 2
    Dernier message: 22/12/2017, 14h30
  3. [Delphi 7] Requête SQL
    Par Hurin dans le forum Bases de données
    Réponses: 2
    Dernier message: 06/07/2008, 11h23
  4. problème de syntaxe delphi pour une requête sql
    Par socooooool dans le forum Bases de données
    Réponses: 12
    Dernier message: 07/07/2006, 17h53
  5. [D5][BDE][Multibase] Récupérer les requêtes SQL d'une TTable
    Par Escandil dans le forum Bases de données
    Réponses: 3
    Dernier message: 11/01/2006, 15h29

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