Problème recherche SQL et filtrage automatique

abcdef70 Messages postés 10 Date d'inscription samedi 12 août 2006 Statut Membre Dernière intervention 4 avril 2009 - 22 janv. 2008 à 18:45
abcdef70 Messages postés 10 Date d'inscription samedi 12 août 2006 Statut Membre Dernière intervention 4 avril 2009 - 31 janv. 2008 à 20:59
Bonjour, Je suis passablement nouveau au niveau de la programmation des base de donnée, alors peut-être me manque-t'il des informations pour résoudre mon problême.

Mon problème lorsqu'une recherche SQL a été faite et que l'utilisateur modifit un des champs constituant la recherche. La recherche est réappliqué aussitot et la fiche sur laquelle l'utilisateur était ne fait plus partie de la recherche.

Par exemple si l'utilisateur recherche toutes les fiches d'employers dont l'adresse et le numéro de téléphone sont vide, afin de remplir les données manquantes, la recherche SQL sera simillaire à ceci:

SELECT * FROM BaseDonneWhere (Adresse '') AND (Telephone '')

Si l'utilisateur commence à modifier l'adresse ou le numéro de téléphone, la fiche disparait de la liste trouvée car le WHERE n'est plus valide(celui-ci spécifit que les deux champs doivent être vide). L'utilisateur ne peut donc pas modifier le deuxième champ. Je sais que je pourrait utiliser un OR à la place de AND, mais j'ai besoin que ma première recherche retourne vraiment uniquement les employers qui ont les deux champs vides

Est-il possible d'effectuer une recherche, et de prévenir que la recherche soit réeffectuée si un des champ est modifié?  L'utilisateur fais une recherche, modifit  les champs à sont gré et vois toujours le total des fiches trouvées au départ, puis lorsqu'il a terminée, il pourrait remettre la recherche à zéro, pour voir toute les fiches existantes.

Pour ceux qui connaisse Filemaker, j'aimerais une recherche comme dans celui-ci. L'utilisateur effectut une recherche, 5 fiches trouvées, il les modifit, puis il sort du mode recherche pour voir toutes les fiches à nouveau.

Merci de vos conseils.

13 réponses

Utilisateur anonyme
22 janv. 2008 à 20:51
Salut,

J'ai rien compris à ta question . En racontant un roman parfois on embrouille les autres .
SELECT * FROM BaseDonne Where (Adresse '') AND (Telephone '')
Tu nous dis que tu recherches dans ta base les champs ou Adresse et Téléphone sont vides. Tu remplis un des champs et cette derniere ne réapparait pas quand tu refais ta recherche : Normal tu a remplis un des champs Donc tu n'as plus "Adresse" et "Téléphone" de vide mais qu'un seul.

Je suis pas expert mais  Soit tu récupère la dernière donnée qui a été modifié, soit tu rajoute un champ "Viewed" (un sorte de Tag) et tu joues avec. Soit tu fais
SELECT * FROM BaseDonne Where (Adresse = '')
SELECT * FROM BaseDonne Where (Telephone = '')

En meme temps je pense qu'il est toujours important dans une base que la dernère que les modifications soit datées. A partir de là, il te serait facile de récupérer cette grandeur.

@++
0
abcdef70 Messages postés 10 Date d'inscription samedi 12 août 2006 Statut Membre Dernière intervention 4 avril 2009
22 janv. 2008 à 21:05
Je ne refais pas une deuxième fois la même recherche. Ce que je parle ce passe dans une seule recherche.
Si tu effectus une recherche WHERE (Champ1 '') AND (Champ2 '') et qu'un DBEdit modifit Champ1, la fiche disparait de la liste trouvée en cours.

Je veux pouvoir effectuer une recherche (qui en fait fitre les fiches), recevoir x nombre de fiches trouvées, les modifiés, puis désactiver le filtrage pour revenir avec toute les fiches.
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
22 janv. 2008 à 21:37
Oui, ce n'est pas difficile.
Tu lances ta requête reliée dans un grid lié à un query1 (select *.*) avec un bouton ou autre..
Ensuite, tu sélectionnes un à un les enregistrements et là soit avec un bouton, soit sur clic-droit tu te cales sur un alia(query2) du query1 relié à un formulaire et tu modifies les données.
Mais bien sûr sans relancer ta requête, et les données ne bougeront pas.
Une fois terminée, tu relances non pas ta requête, mais tu fais un refresh du query1.

cantador
0
abcdef70 Messages postés 10 Date d'inscription samedi 12 août 2006 Statut Membre Dernière intervention 4 avril 2009
22 janv. 2008 à 22:28
Je ne suis pas sur de comprendre ce que tu entend par "tu te cales sur un alia(query2) du query1".
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
23 janv. 2008 à 09:31
Tu peux utiliser autant de query que tu veux tous reliés à la même table et faire des opérations différentes :

ex : l'un ouvrira tous les champs : select * from MaTable
      un autre mettra en place un filtre : SELECT * FROM MaTable (et non BaseDonne..)Where (Adresse '') AND (Telephone '')

Encore un autre fera un update ou un insert.. etc etc..

Ces opérations peuvent même être concomittentes..

Une fois qu'un requête est lancée et que les données résultantes sont affichées dans un Grid par exemple, elles ne peuvent PLUS bouger car c'est comme ci on avait transférer l'extraction dans une table temporaire.
Mais pendant cette opération ou après cette dernière, tu peux faire tout autre chose !

cantador
0
abcdef70 Messages postés 10 Date d'inscription samedi 12 août 2006 Statut Membre Dernière intervention 4 avril 2009
23 janv. 2008 à 21:06
Oui, j'ai remarqué que l'on peut mettre deux Query sur la même table, et que ceux ci peuvent retourner deux chose différente.

J'utilise les composents Absolute Database qui contient un composent Table, Query, Session, etc. C'est peut-être celà la différence. Je croyais que ces composents fonctionnait de la même façon que ceux de la BDE, mais je me rend compte que le Query a quelques différence, entre autre, lorsqu'il est utilisé avec une grille ou des DBEdit, si ont modifit ces dernier, le Query met la base de donnée à jour par lui même. Il agit comme est une Table ordinaire. C'est pour cette raison que si j'effectue une recherche du genre:
Where (Adresse '') AND (Telephone '')

et que je modifit le champ adresse via un DBEdit, la fiche est retiré de la liste trouvé car celà ne correspond plus aux critères de recherche.

Je peux bien entendu utiliser le Query pour afficher la recherche dans une grille, et une Table et des DBEdit pour modifié l'enregistrement sélectionné dans la grille, mais dans ce cas malheureusement, ce qui est affiché dans la grille n'est pas mis à jour, donc dans la grille adresse et téléphone paraissent vide, mais ils ont bien été modifié par le composent Table.

Je ne sais pas si la même chose se produit avec la BDE, si oui, avez-vous une technique pour mettre à jour la grille lorsqu'un enregistrement a été modifié, me sans sans ré-exécuter le Query associé à la grille (qui ferait disparaitre l'enregistrement qui n'est plus valide)?

Michel
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
23 janv. 2008 à 21:42
cantador
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
23 janv. 2008 à 21:45
désolé ya un truc qui déconne..

cantador
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
23 janv. 2008 à 21:57
Il y a une différence essentielle :

Un filtre cà marche en permanence et un query est un instantané.

Pour ton souci, tu peux utiliser un DBGrid, un bouton bascule (TSpeedButton avec la propriété AllowUp à true et GroupeIndex à -1)
+ les DBEDIT + DBNavigator
Tu commences par ouvrir ton prog en plaçant directement ton SQL filtrant dans le Query.
Cà marche avec BDE + paradox ou FireBird (+ ODBC)
Tu verras que lorsque tu modifies un enregistrement que celui reste bien à sa place jusqu'à ce que tu cliques sur le bouton :

Voici le code du bouton :
procedure TFExercice.SBRequeteClick(Sender: TObject);
begin
  if SBRequete.Down then
  begin
    SBRequete.Caption := 'FILTRE';
    with QEmploye.SQL do
    begin
      Clear;
      Add('SELECT * FROM EMPLOYE ');
      QEmploye.Open;
    end;
  end
  else
  begin
    SBRequete.Caption := 'TOUT VOIR';
    with QEmploye.SQL do
    begin
      Clear;
      Add('SELECT * FROM EMPLOYE ');
      Add('WHERE (ADRESSE =:ADR) AND (TEL =:CTEL) ');
      QEmploye.ParamByName('ADR').Value := '';
      QEmploye.ParamByName('CTEL').Value := '';
      QEmploye.Open;
    end;
  end;
end;

cantador
0
abcdef70 Messages postés 10 Date d'inscription samedi 12 août 2006 Statut Membre Dernière intervention 4 avril 2009
24 janv. 2008 à 00:20
Merci Cantador,

J'ai essayé l'exemple que vous m'avez fourni, et j'ai le même problème avec le BDE.

Pour refaire exactement ce que j'ai fais, placez les composents suivant sur une forme vide sans changer leurs noms:

Query1: TQuery
Datasource1: TDatasource
DBGrid1: TDBGrid
SpeedButton1: TSpeedButton

--- pour vous facilitez la tâche, repassez le code suivant dans l'événement FormOnCreate:

procedure TForm1.FormCreate(Sender: TObject);
begin
    SpeedButton1.Caption := 'TOUS VISIBLE';
    SpeedButton1.AllowAllUp := True;
    SpeedButton1.GroupIndex := -1;
    DBGrid1.DataSource := Datasource1;
    Datasource1.DataSet := Query1;
    Query1.DatabaseName := 'DBDEMOS';
    Query1.RequestLive := True;
    Query1.SQL.Add('SELECT * From Employee.db');
    Query1.Active := True;
end;

--- Repassez le code suivant dans l'événement OnClick du SpeedButton1:

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
    with Query1 do
    Begin
        SQL.Clear;
        SQL.Add('SELECT * FROM EMPLOYEE.db ');
        if SpeedButton1.Down then
        begin
            SpeedButton1.Caption := 'FILTRÉ';
            SQL.Add('WHERE (LastName Like :LN) ');
            ParamByName('LN').Value := 'B%';
        End
        Else
        begin
            SpeedButton1.Caption := 'TOUS VISIBLE';
        end;
        Open;
    End;
end;

--- Faites tourner votre application. en appuyant sur le SpeedButton, seul les noms de famille(LastName) commençant par B... sont affiché. Maintenant modifiez un de ces noms, par exemple pour TREVORS, et vous remarquerez que lorsque vous sélectionnez un autre enregistrement, celui que vous avez modifié disparaîtra.

J'utilise Delphi 7, dites-moi si vous avez le même problême avec l'exemple ci dessus?

Michel
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
24 janv. 2008 à 11:18
Oui effectivement çà vient des tables paradox + BDE qui lors d'une validation déclenche un rafraîchissement..
Autrement dit, cela revient à écrire un filtre !

Moi, mon test marchait MAIS avec une base Firebird..(base.fdb) et la connexion via l'ODBC du BDE.

Une autre bonne raison de changer de SGBD..

Mais peut-être il y a moyen de désactiver le refresh ?
Je cherche..

cantador
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
24 janv. 2008 à 11:47
Voilà déjà une explication :

"En outre Paradox rafraîchit automatiquement les données en cas de changement, de manière cyclique (3 à 5 secondes en principe). "

cantador
0
abcdef70 Messages postés 10 Date d'inscription samedi 12 août 2006 Statut Membre Dernière intervention 4 avril 2009
31 janv. 2008 à 20:59
Je vais tenter de trouver une autre solution, merci pour toutes les informations.
0
Rejoignez-nous