[newbie] Comment mettre à jour les données d'un DBgrid?

Utilisateur anonyme - 10 août 2008 à 11:18
 Utilisateur anonyme - 12 août 2008 à 10:09
Bonjour

J'utilise le wrapper de type BDE de Aducom pour accéder à une base SQLite, et j'aimerais utiliser un DBgrid pour afficher les données avec un TQuery + SELECT, tout en permettant à l'utiliser de les modifier (pas en direct via DBnavigator : l'utilisateur clique sur un bouton, je fais le INSERT, j'enregistre dans la BD, et je rafraîchis le grid).

Je n'arrive pas à trouver un exemple de ce type d'utilisation. A ce point des choses, j'ai du code qui marche en utilisant deux TQuery, un pour le SELECT, l'autre pour le INSERT (si je n'utilise qu'un seul TQuery que je ferme pour faire un ExecSQL avant de faire un nouveau SELECT suivi d'un Open, Delphi déclenche une exception juste après le ExecSQL).

J'aimerais vérifier deux points:
1. Faut-il effectivement deux TQuery? N'y a-t-il pas moyen de n'en utiliser qu'un pour gérer l'échange de données entre la BD et le grid (via le DataSource, bien sûr)?
2. Dans quel cas dois-je utiliser un TUpdateSQL? Il semble que la solution normale est de combiner un TQuery pour le SELECT, et un TUpdateSQL pour les mises à jour, mais je n'arrive pas à trouver un exemple avec un DBgrid.

Merci pour toute info :)

PS : mon code qui marche

10 réponses

cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
10 août 2008 à 11:47
bonjour,

D'abord, une seule question à la fois...

à chaud :

(si je n'utilise qu'un seul TQuery que je ferme pour faire un ExecSQL avant de faire un nouveau SELECT suivi d'un Open, Delphi déclenche une exception juste après le ExecSQL).

Normal, la requête est modifiée..
et je ne mettrai pas un CREATE sur un OnActivate..

j'ai pas tout regardé encore..

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
10 août 2008 à 12:32
procedure TForm1.Button1Click(Sender: TObject);
begin
//Use a second TQuery, to perform changes, and avoid exception after ExecSQL
  with Query1 do
  begin
    Close;
    SQL.Clear;
    SQL.Text := 'INSERT INTO books (isbn,language) VALUES (NULL, :a)';
    Params[0].AsString := 'test';
    ExecSQL;
  end;


  ASQLite3Query1.Refresh;
end;

mettre un point d'arrêt sur le ExecSQL et tout tester :
- est ce ma base est ouverte ?
- est ce que ma table existe ?
- est ce que mes champs sont bien créés et corrects ?
- est ce que ma requête est bonne ?
- est ce que Null est autorisé dans isbn ?
(tester Form1.Query1.SQL[0] +  Form1.Query1.SQL[1]  + Form1.Query1.SQL[2] etc etc.. jusqu'à la fin..

remplacer par :
ParamByName('a').Value : = 'test';
au cas il y aurait un caractère indésirable...

cantador
0
Utilisateur anonyme
10 août 2008 à 18:26
Merci pour ta réponse. Visiblement, je dois faire un truc très peu orthodoxe pour ne pas trouver d'exemple et ne pas recevoir de réponse dans les forums Delphi où j'ai déjà demandé.

Personne n'utilise de TQuery avec un DBgrid et permet à l'utilisateur de modifier le contenu du grid via un bouton? Tout le monde utilise le DBgrid avec un TTable, jamais avec un TQuery?

> Normal, la requête est modifiée..

Oui, mais je pensais que ça serait OK si je fermais le TQuery avant de faire un ExecSQL, avant de refaire un SELECT + Open.

En même temps, ça ne me gêne pas de combiner TQuery avec un TUpdateSQL mais... quelqu'un a-t-il un exemple de code qui marche avec un DBgrid?

> et je ne mettrai pas un CREATE sur un OnActivate..

Dans quel évènement est-il recommandé de mettre ça?

> mettre un point d'arrêt sur le ExecSQL et tout tester :

Ca fonctionne correctement, au sens où la base est créée et 'enregistrement ajouté : on le voit si on relance l'appli après l'exception provoquée par ExecSQL.

> (tester Form1.Query1.SQL[0] +  Form1.Query1.SQL[1]  + Form1.Query1.SQL[2] etc etc.. jusqu'à la fin..

Ce code provoque une exception:
Project Project1.exe raised exception class EStringListError with message 'List index out of bounds (1)'.

  With ASQLite3Query1 do begin
    ShowMessage(SQL[0] +  SQL[1]  + SQL[2]);
  end;


> remplacer par : ParamByName('a').Value := 'test'; au cas il y aurait un caractère indésirable...

Ce composant TQuery ne supporte pas cette propriété. Mais de toute façon, l'enregistrement semble correctement créé, lorsque je fais un SELECT par la suite.

Merci.
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
10 août 2008 à 18:58
Tout le monde utilise le DBgrid avec un TTable, jamais avec un TQuery?

Effectivement au début, on prend un TTable et puis après, on utilise le query.
Pour ma part, je ne me sers que des Query !

Query1.Append;
Query1.Insert;
Query1.Edit;
Query1.Post

Tout ces procédures fonctionnent très bien
et avec le Query (BDE) :
Query1.ParamByName('param').Value :=
ca marche nickel.

> et je ne mettrai pas un CREATE sur un OnActivate..
Dans quel évènement est-il recommandé de mettre ça?

Le OnActivate a la particularité de se déclencher sur bcp d'actions
Autrement dit chaque fois que tu vas faire un  truc, le test sur le CREATE va s'effectuer ..

Quand on crée une table, on la crée une seule fois..
donc je mettrais la création sur l'évènement ONCREATE de la forme.

Project Project1.exe raised exception class EStringListError with message 'List index out of bounds (1)'.
désolé, il faut faire cette manip sur CTRL  F7 (évaluation)
et il faut ajuster, tu en a mis certainement un ou plusieurs en trop.

cantador
0

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

Posez votre question
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
10 août 2008 à 22:53
Vite fait ...
PRIMO :
Remplacer : " With ASQLite3Query1 do begin
    ShowMessage(SQL[0] +  SQL[1]  + SQL[2]);"

par
With ASQLite3Query1 do begin
    ShowMessage(SQL.text);

DEUXIO :
Quand utiliser un TUpdateSql ? C'est simple : quand la requête renvoie un ensemble de données non modifiables (requête multitables, interrogation d'une vue, etc).

May Delphi be with you !
<hr color="#008000" />Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
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
10 août 2008 à 23:14
Salut Delphiprog !

With ASQLite3Query1 do begin
    ShowMessage(SQL.text);

je préfére le point d'arrêt qui évite de modifier le code...

Quand utiliser un TUpdateSql ?

le mieux, c'est peut-être jamais..

cantador
0
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
10 août 2008 à 23:20
Quand utiliser un TUpdateSql ? le mieux, c'est peut-être jamais..

Que nenni, mon ami ! Dans les cas que j'ai cité, tu n'as pas le choix. Enfin si, mais au prix d'une gymnastique délicate alors que le TUpdateSql te permet de gérer les update, insert et delete très facilement. De même qu'on peut écrire du code en utilisant notepad...

May Delphi be with you !
<hr color="#008000" />Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
0
Utilisateur anonyme
11 août 2008 à 08:50
Merci pour vos réponses, mais à ce point, je n'ai tj rien qui marche :-/

Je ne veux pas utiliser un TTable parce que 1) j'ai besoin de n'afficher que certains enregistrements, d'où filtre avec SELECT, et 2) il risque d'y avoir pas mal de données, donc pas envie de tout récupérer au départ. Ou alors on peut faire une sélection même avec un TTable?

Auriez-vous un exemple simple d'utilisation d'un TQuery + TUpdateSQL + TDBGrid et un bouton qui permet d'envoyer un INSERT ou UPDATE, et de finir avec un rafraîchissement de la grille?

Question subsidiaire : quels problèmes pose l'utilisation d'un TUpdateSQL ("Quand utiliser un TUpdateSql ? -> le mieux, c'est peut-être jamais..")?

Merci.
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
11 août 2008 à 13:20
Tout dépend en fait du fonctionnement de ton appli...
Si c'est une petite appli locale, alors, tu peux te passer du TUpdateSQL.

En revanche, si ton appli est en client serveur, avec beaucoup de transactions alors, je rejoins en partie delphiprog car ce composant permet
les mises à jour en mémoire cache permettant des transactions moins nombreuses qui prennent moins de temps et assurant donc un trafic réseau minimal.

Mais ce compo a mal vielli et donne quelques diffcultés de temps en temps..
(par contre chaque compo db aware a son propre TUpdateSQL qui suit évidemment l'évolution)
Mais, (il y a toujours un mais) aujourd'hui, le mieux encore est d'utiliser des procédures stockées directements dans la base sur le serveur.
Mais ceci est une autre histoire...

Voilà un lien sur exemple fourni par Borland lui-même (la seule démo)
c:\Program Files\Borland\Delphi7\Demos\Db\CacheDup\

cantador
0
Utilisateur anonyme
12 août 2008 à 10:09
Merci pour les infos. Je vais regarder voir s'il vaut mieux utiliser TTable plutôt.
0
Rejoignez-nous