Bonjour,
Puis-je utiliser les composants Interbase (TIBdataset, ...) de DelphiXE2 pour manipuler les tables d'une base de donnée Firebird 2.5
Merci.
Bonjour,
Puis-je utiliser les composants Interbase (TIBdataset, ...) de DelphiXE2 pour manipuler les tables d'une base de donnée Firebird 2.5
Merci.
C'est pas recommandé, mais beaucoup le font avec succès.
Cordialement
André
Alors qu'elle est la meilleur solution SVP ?
Pour ma part j'utilise les UIB associés a des clientdataset, et ça fonctionne plutôt bien.
André
Cela voudrait dire que tu as Delphi XE2 pro , car avec la version entreprise il y a DBExpress . Sinon , j'ai essayé avec succès les ZeosDBO voir aussi FireDac (ex Anydac ) qui doit pouvoir s'acheter ?
MVP Embarcadero
Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
SGBD : Firebird 2.5, 3, SQLite
générateurs États : FastReport, Rave, QuickReport
OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd
a prendre en main, mais il faut maitriser les techniques de déploiement, a savoir une dll a déployer et un chemin d’accès pas forcement facile a régler lors du déploiement.
andré
Pour ma part je me suis lancé dans un nouveau projet avec les DBExpress pour deux raisons: j'avais peur si cette appli est amenée à durer que les IBX tombent en rad et je n'ai pas trouvé et réussi à installer de composant permettant un accès directe aux données avec le UIB (je veux bien ta méthode alheuredudejeuner avec les ClientDataSet)
Au final c'est pas forcément reluisant le TSimpleDataSet mais bon, ça fonctionne quand même dans la majorité des cas...
DBExpress n'a jamais été ma tasse de thé , mais depuis l'annonce de FireDac , je ronge mon frein , je pense que je vais sauter le pas XE3 même si il n'y a toujours pas la compilation LINUX .
ZEOSDBO n'est pas mal non plus , bien que composant tiers , très pratique pour les gens venant du BDE , installable sur une version pro et ... Gratuit , UIB est un peu plus complexe a prendre en main , je ne pense pas que l'on puisse l'utiliser pour un programme client DataSnap , idem pour ZEOS .
Je m'orienterai donc vers Firedac pour mes nouveaux devs. (j'en ai pas mal en cartons)
MVP Embarcadero
Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
SGBD : Firebird 2.5, 3, SQLite
générateurs États : FastReport, Rave, QuickReport
OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd
Je pense le contraire... que ce soit pour des ensembles de données ou des données ponctuelles.
Je pense aussi qu'il y a un petite confusion. Les composants UIB seront côté serveur. Le client datasnap se moque que de l'autre côté on ait de l'ADO, du dbexpress, de l'UIB, du BDE (Soyons fou ! )
Il y a des déjà des exemples de ce type (je pense au Framework delphi orm).
Le seul inconvénient (si je puis dire), c'est qu'il faut une version entreprise de Delphi ou de Rad Studio, ce qui n'est pas à la portée de tout le monde...
Philippe.
MVP Embarcadero
Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
SGBD : Firebird 2.5, 3, SQLite
générateurs États : FastReport, Rave, QuickReport
OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd
Je pourrai faire mieux, mais je suis arrêter à ce stade car malgré tous les tutos, je n'ai pas pu utiliser la gestion du runtime et du designtime pour la création de composant.
Ce modèle fonctionne sous D7, D9 et XE2, cependant il ne permet plus d'utiliser les événements beforepost, afteropen et beforedelete du clientdataset.
Je n'ai pas tester ce composant car c'est mon modèle de base qui me permet de créer mes modèles d'utilisation, j'ai juste ajouter dernièrementqui me permet de faire un select avec paramètre.
Code : Sélectionner tout - Visualiser dans une fenêtre à part procédure SelectData(q : TUIBQuery);
Pour aller plus loin, il faut gérer cette histoire de runtime et de designtime, pour appeler le nom des champs pour une table et avec les rtti, il y a un super exemple là : http://www.alberton.info/firebird_sq...l#.UXe1u8pe-SI et se passer de l'écriture à la main des champs et des mises à jour. Cependant dans le cas de requêtes avec des jointure, ça me permet de gérer très finement les Mises à jour.
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308 unit uCDSVulcainBase; interface uses System.SysUtils, System.Classes, Data.DB, Datasnap.DBClient, uib, dialogs, uSQL; type TCDSVulcainBase = class(TClientDataSet) private { Déclarations privées } procedure odAfterOpen(DataSet: TDataSet); procedure odbeforePost(Dataset: Tdataset); procedure odBeforeDelete(Dataset: Tdataset); procedure getData(q:Tuibquery); protected { Déclarations protégées } public { Déclarations publiques } UpdateBase : Boolean; fsqlSelect : string; fsqlUpdate : string; fUIBDatabase : TUIBDataBase; fUIBdbConnected : Boolean; Procedure SetUIBDatabase(UIBDatabase: TUIBDataBase); procedure SetUIBdbConnected(UIBdbConnected: Boolean); procedure SetsqlSelect(sqlSelect: string); procedure SetsqlUpdate(sqlUpdate: string); procedure RefreshData; procedure SelectData(q : TUIBQuery); // procédures et fonction de l'objet constructor Create(AOwner: TComponent); override; destructor Destroy; override; published { Déclarations publiées } property UIBDatabase: TUIBDataBase read fUIBDatabase write SetUIBDatabase; property UIBdbConnected :Boolean read fUIBdbConnected write SetUIBdbConnected ; property sqlSelect:string read fsqlSelect write SetsqlSelect; property sqlUpdate:string read fsqlUpdate write SetsqlUpdate; end; procedure Register; implementation procedure Register; begin RegisterComponents('VulcainLogistique', [TCDSVulcainBase]); end; { TcdsEntreprisesDocuments } constructor TCDSVulcainBase.Create(AOwner: TComponent); begin inherited; // with FieldDefs do // begin // Clear; // Add('ID_SITE',ftInteger); // Add('UTILISATEUR',ftString, 20); // Add('MOT_DE_PASSE',ftString, 10); // Add('ROLE',ftString, 10); // Add('NOM',ftString, 30); // Add('PRENOM',ftString, 30); // Add('PHOTO',ftGraphic); // // end; // UpdateBase:=True; // sqlselect :='select * from USERS' ; // sqlUpdate :='UPDATE OR INSERT INTO USERS' // +'(ID_SITE, ' // +'UTILISATEUR, ' // +'MOT_DE_PASSE, ' // +'ROLE, ' // +'NOM, ' // +'PRENOM, ' // +'PHOTO) ' // +'VALUES ' // +'(:sID_SITE, ' // +':sUTILISATEUR, ' // +':sMOT_DE_PASSE, ' // +':sROLE, ' // +':sNOM, ' // +':sPRENOM, ' // +':sPHOTO )' // +'MATCHING(UTILISATEUR) '; // AfterOpen:=doAfterOpen; // BeforePost:=dobeforePost; // BeforeDelete:= doBeforeDelete; end; destructor TCDSVulcainBase.Destroy; begin inherited; end; procedure TCDSVulcainBase.getData(q: Tuibquery); var qp : TUIBQuery; Stream: TMemoryStream; begin // try // EmptyDataSet; // q.Open; // while not q.eof do // begin // Insert; // FieldByName('ID_SITE').AsInteger := q.Fields.ByNameAsInteger['ID_SITE']; // // FieldByName('UTILISATEUR').AsString := q.Fields.ByNameAsString['UTILISATEUR']; // FieldByName('MOT_DE_PASSE').AsString := q.Fields.ByNameAsString['MOT_DE_PASSE']; // FieldByName('ROLE').AsString := q.Fields.ByNameAsString['ROLE']; // FieldByName('NOM').AsString := q.Fields.ByNameAsString['NOM']; // FieldByName('PRENOM').AsString := q.Fields.ByNameAsString['PRENOM']; // Stream:=TMemoryStream.Create; // try // q.Fields.ReadBlob('PHOTO', Stream); // TBlobField(FieldByName('PHOTO')).LoadFromStream(Stream); // finally // FreeAndNil(Stream); // end; // Post; // q.Next; // end; // q.Close; // UIBDatabase.Connected := False; // except // on E: Exception do // ShowMessage('Erreur :' + E.Message); // end; end; procedure TCDSVulcainBase.odAfterOpen(DataSet: TDataSet); var t: TUIBTransaction; q: TUIBQuery; Stream: TMemoryStream; begin if UIBDatabase=nil then else begin UpdateBase:=false; q :=TUIBQuery.Create(nil); t:=TUIBTransaction.Create(nil); t.DataBase:=UIBDatabase; with q do begin Transaction:=t; SQL.Clear; SQL.Add(sqlSelect); FetchBlobs:=True; end; try getData(q); finally FreeAndNil(q); FreeAndNil(t); UpdateBase:=true; end; end; end; procedure TCDSVulcainBase.odBeforeDelete(Dataset: Tdataset); var t: TUIBTransaction; q: TUIBQuery; begin // if UpdateBase=true then // begin // if UIBDatabase<>nil then // begin // q:=TUIBQuery.Create(nil); // t:=TUIBTransaction.Create(nil); // try // UpdateBase :=False; // t.DataBase:=UIBDatabase; // q.Transaction:=t; // with q do // begin // SQL.Clear; // SQL.Add('DELETE FROM USERS WHERE ID = :sID'); // Params.ByNameAsString['sID']:=FieldByName('ID').AsString ; // try // q.Open; // except // on E : Exception do ShowMessage('erreur: '+E.Message); // end; // end; // finally // t.Free; // q.Free; // UpdateBase:=True; // if UIBdbConnected then else UIBDatabase.Connected:=false; // end; // end; // end; end; procedure TCDSVulcainBase.odbeforePost(Dataset: Tdataset); var t: TUIBTransaction; q: TUIBQuery; Stream: TStream; begin // if UpdateBase=true then // begin // if UIBDatabase<>nil then // begin // q:=TUIBQuery.Create(nil); // t:=TUIBTransaction.Create(nil); // Stream:=createBlobStream(FieldByName('PHOTO'),bmread); // try // UpdateBase :=False; // t.DataBase:=UIBDatabase; // q.Transaction:=t; // with q do // begin // SQL.Clear; // SQL.Add(sqlUpdate); // if (FieldByName('ID').IsNull) or ( FieldByName('ID').AsInteger<1) // then Params.ByNameAsInteger['sID']:= GetID('tabletabletable', UIBDatabase) // else Params.ByNameAsInteger['sID']:=FieldByName('ID').AsInteger ; // Params.ByNameAsInteger['sID_SITE']:=FieldByName('ID_SITE').AsInteger ; // Params.ByNameAsString['sUTILISATEUR']:=FieldByName('UTILISATEUR').AsString ; // Params.ByNameAsString['sMOT_DE_PASSE']:=FieldByName('MOT_DE_PASSE').AsString ; // Params.ByNameAsString['sROLE']:=FieldByName('ROLE').AsString ; // Params.ByNameAsString['sNOM']:=FieldByName('NOM').AsString ; // Params.ByNameAsString['sPRENOM']:=FieldByName('PRENOM').AsString ; // // q.ParamsSetBlob('sPhoto', Stream); // // try // q.Open; // if UIBdbConnected then else UIBDatabase.Connected:=False; // except // on E : Exception do ShowMessage('erreur: '+E.Message); // end; // end; // finally // t.Free; // q.Free; // Stream.Free; // UpdateBase:=True; // end; // end; // end; end; procedure TCDSVulcainBase.RefreshData; begin EmptyDataSet; Close; Open; end; procedure TCDSVulcainBase.SelectData(q: TUIBQuery); var t : TUIBTransaction; begin if UIBDatabase=nil then else begin UpdateBase:=false; t:=TUIBTransaction.Create(nil); t.DataBase:=UIBDatabase; with q do begin Transaction:=t; FetchBlobs:=True; end; try getData(q); finally FreeAndNil(t); UpdateBase:=true; end; end; end; procedure TCDSVulcainBase.SetsqlSelect(sqlSelect: string); begin fsqlselect:=sqlselect; end; procedure TCDSVulcainBase.SetsqlUpdate(sqlUpdate: string); begin fsqlUpdate:=sqlUpdate; end; procedure TCDSVulcainBase.SetUIBDatabase(UIBDatabase: TUIBDataBase); begin fUIBDatabase:=UIBDatabase; end; procedure TCDSVulcainBase.SetUIBdbConnected(UIBdbConnected: Boolean); begin fUIBdbConnected:=UIBdbConnected; end; end.
Bonjour,
J'ai 2 ou 3 remarques hors sujet concernant le code présenté :
Quel le but de ce mécanisme sachant qu'un clientdataset peut à priori être rattaché aux composants uibdataset ? gérer différemment les retours vers la bd ?
Quel est l'intérêt des variables publiques rattachées à des propriétés publiés (erreur de copie de code) ?
Quel est l'intérêt d'écrire if UIBDatabase=nil then else (ça me parait dangereux) ?
Philippe.
1/le but, je n'ai pas pu utiliser le gzfbdataset avec XE2, je voulais rester compatible avec UIB Et les différentes versions de firebird. mes tables sont reprises dans des dizaines de fiches, je n'ai pas a tout réécrire pour les utiliser en lecture écriture, ce que ne fait pas UIB.
2/ Je ne sais pas, peut-être du code à reprendre..
3/if UIBDatabase=nil then else ..ben si la propriété uibdataset du composant n'est pas renseignée, c'est pas la peine d'aller lire/écrire dans la base de données.
André
PS le gzfbdataset a été mis à jour pour XE2 récemment.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager