Vous êtes sur la page 1sur 38

Interbase dbExpress.NET - John COLIBRI.

• abstract: utilisation de dbExpress avec Interbase et Delphi 8.


• mots clé:tutorial - Interbase - dbExpress - Delphi 8 - VCL.NET -
DataSnap - Midas
• logiciel utilisé: Windows XP, Delphi 8, Interbase 6, 7
ou Firebird 1 ou 1.5
• matériel utilisé: Pentium 1.400Mhz, 256 M de mémoire
• champ d'application: Delphi 8 - .NET
• niveau: développeur Delphi et Base de Données
• plan:
o Introduction
o Connexion à la base
o Créer une Table
o Lire et Afficher
o Le mode nomade
o Modifier des Données
o Télécharger les Exemples
o Conclusion

1 - Introduction
Cet article va vous indiquer comment gérer des données en
utiliser Interbase fourni avec Delphi 8 en utilisant dbExpress.

Nous avons présenté les autres façons d'utiliser Interbase:

• le tutorial interbase: comment utiliser des bases de données en


mode Client Serveur (Delphi 6, Ibx). L'article d'initiation le plus complet
• Interbase dbExpresss: le mode dbExpress (Delphi 6, dbExpress). Le mode qui
permet le mieux de comprendre l'architecture Ado.Net qui en est
directement issue
• Interbase Ibx.Net: le portage sous .Net de la
mécanique Ibx (Delphi 8, Ibx.Net). Le moyen le plus simple
d'utiliser Interbase et Delphi 8. Contient aussi un comparatif de toutes ces
architectures avec les schémas correspondants
• Delphi 8 Ado.Net: sous Windows Forms, en l'absence de couche spécifique
à Interbase nous pouvons utiliser une mécanique similaire à Odbc et proche
d'Ado sous Win32. Cet article présente ce fonctionnement
• Interbase Borland Data Provider: la voie royale sous Windows Forms, et
pour toutes les base, même pour tous les langages
La présentation des différentes possibilités ne sera pas reprise ici. Nous nous
concentrerons sur l'utilisation de dbExpress.Net.

Nous nous adressons pour ce tutorial à un programmeur Delphi ayant:

• une idée élémentaire de Delphi: Palette, Inspecteur, OnClick.


• déjà pratiqué un peu la gestion de données avec SQL: SELECT, INSERT INTO,
UPDATE . Si tel n'est pas le cas, reportez vous aux articles précédents (le
tutorial Interbase pour les techniques SQL, Interbase dbExpress pour le
détail de dbExpress en mode Win32 ou Interbase Ibx.Net) pour les
traitements sous Vcl.Net.

Notre but étant ici de vous montrer comment utiliser dbExpress en Delphi 8, nous
n'avons pas présenté un tutorial intégral. Les articles précédents contiennent aussi
des exemples plus nombreux (automatisation, script) ou programmés de façon
légèrement différente (sous procédures différentes). Parcourez-les au besoin
avant ou après cet article.

2 - Connection, Création de table, Insertion


2.1 - Préparation
La création de la base ne peut être réalisée par des composants dbExpress: il faut
utiliser un utilitaire propre à chaque moteur (IbConsole pour Interbase) ou les
contrôles Interbase Express. Reportez-vous aux articles sur dbExpress pour voir
comment faire.

Pour cette présentation, nous allons simplement utiliser une base crée auparavant.
Nous pourrions utiliser celle installée par Borland, mais le chemin dépendant de
votre machine ("program files" avec Windows US ou "fichiers communs"
avec Windows Français), nous préférons rapatrier la base dans un chemin proche de
notre projet Delphi.

Nos exemples utiliseront la base INSTITUT_PASCAL.GDB de nos articles


précédents. Vous pouvez aussi utiliser la base démonstration
de Borland EMPLOYEE.GDB. Comme nous créons intégralement les tables, il
suffira de changer le nom de la base.

Par conséquent:

• vérifier qu'il existe un répertoire ..\_data (dossier au même niveau que le


dossier contenant le .DPR)
• copiez la base dans ce dossier
• renommez la base INSTITUT_PASCAL_4.GDB (le changement de nom d'une
base local par un Explorateur Windows n'empêche pas son utilisation. Si
cette base est connectée, débranchez-la auparavant. Si vous n'y arrivez pas,
utilisez-la telle quelle, mais changez les noms dans les exemples ci-dessous)

2.2 - La connection
Pour nous connecter à une base Interbase nous allons utiliser un
composant SqlConnection.

Ce composant doit être initialisé avec:

• dans DriverName, le nom du pilote Interbase:


Interbase
• dans ConnectionName le nom de la connexion:
IbLocal
• dans Params les paramètres propres à Interbase, tels que le nom
d'utilisateur, le mot de passe, le chemin où se trouve le fichier .GDB etc

Pour spécifier l'endroit où se trouve le fichier .GDB, nous fournissons:

• soit le chemin, si nous travaillons en local:


c:\programs\interbase\data\Institut_Pascal.gdb
ou
..\data\Institut_Pascal.gdb
• soit l'URL du PC qui héberge le Serveur:
127.0.0.1\ c:\programs\interbase\data\Institut_Pascal.gdb
HostName\ c:\programs\interbase\data\Institut_Pascal.gdb
www.jcolibri.com\ c:\programs\interbase\data\Institut_Pascal.gdb

Pour initialiser tous ces paramètres, nous employons l'éditeur de tSqlConnection:


créez une nouvelle application et appelez-la "p_net_dbx_create_table"

sélectionnez dans la page "dbExpress" de la Palette le composant SqlConnection:


et posez-le sur la tForm
cliquez deux fois sur SqlConnection1 pour ouvrir l'éditeur de tIbDatabase

Delphi ouvre le dialogue de connection:


Le premier pilote est utilisé par défaut (ASAConnection dans notre cas)

sélectionnez dans la combobox "Driver Name" le pilote "Interbase"

dans le listbox "Connection Name" sélectionnez "IbConnection"

Delphi affiche les paramètres du pilote Interbase

dans la ligne "Database" de la listbox de droite

• dans "Database", tapez le nom de la base


..\data\Institut_Pascal_4.gdb
• dans "Dialect", tapez la valeur 3
• dans "User Name", tapez
SYSDBA
• dans "PassWord", tapez
masterkey

le résultat est:
fermez l'éditeur en cliquant "OK"

sélectionnez dans l'Inspecteur d'Objet la propriété LoginPrompt et basculez sa valeur sur False

sélectionnez Connected et basculez sa valeur sur True

au bout d'un "petit" instant, la valeur bascule sur True

Notez que:

• lorsque nous avons créé la base, nous avons choisi le "dialecte 3". C'est la
version Sql du moteur
• lorsque nous connectons la base, nous avons choisi le "dialecte 3": c'est le
dialecte du client Interbase.
• la connection est le test IMPERATIF pour vérifier que nous pouvons
travailler en Interbase. Nous recommandons d'effectuer cette connection
systématiquement avant de poser des tonnes de composants sur
la tForm ou d'écrire des milliers de lignes
• si nous connectons la base en mode conception, Delphi ouvrira aussi la base
lorsque l'exécution sera lancée. Ces deux connections sont comptabilisés
par le gestionnaire de licences Interbase comme 2 connections séparées (ce
sont bien deux processus Windows).

Si vous travaillez en utilisant la version Delphi d'Interbase, il vaut mieux


fermer la connection en mode conception, puis la rouvrir lors de l'exécution.
En fait, chaque accès à Interbase ouvrira automatiquement la connexion.
Nous pouvons donc:

o soit laisse dbExpress ouvrir automatiquement la connexion


o soit ouvrir la connexion lors de l'exécution en appelant;
tSqlConnection.Connected:= True;

Nous allons donc fermer la connexion en mode conception:

sélectionnez SqlConnection1, sélectionnez dans l'Inspecteur d'Objet la


propriété Connected et basculez sa valeur sur False

3 - Créer et remplir une Table


3.1 - Principe
Nous allons créer une table contenant pour chaque formation:

• un code (par exemple 8)


• un nom (par exemple "Delphi Interbase")
• le nombre de jours (par exemple 3)
• un prix (par exemple 1.400)

Pour cela nous devons envoyer une requête en langage SQL vers
le Serveur Interbase.

La syntaxe de cette requête est:

CREATE TABLE formations


(f_numero INTEGER, f_nom CHARACTER(11), f_jours INTEGER,
f_prix NUMERIC(5, 2) )

Il suffit donc de choisir un nom de table, et le nom de chaque colonne avec son
type.

Parmi les types autorisés par Interbase citons:


• INTEGER pour les valeurs entières 32 bits
• SMALLINT pour les valeurs entières 16 bits
• NUMERIC(decimales, précision) pour une valeur numérique flottante
• DATE pour une date
• CHARACTER(taille) pour des caractères

Pour envoyer cette requête vers le Serveur:

• nous utilisons un tSqlConnection qui assurera la connection vers le Serveur


• nous utilisons un tSqlQuery
o nous le relions à tSqlConnection
o nous plaçons la requête SQL dans sa propriété ISqlQuery.SQL (via
l'Inspecteur ou en code)
o nous appelons tSqlQuery.ExecSql

3.2 - Utilisation de SQL


La requête à envoyer au Serveur est placée dans tSqlQuery.Sql. tSqlQuery.Sql est
un descendant de tStrings. Nous pouvons donc utiliser, par exemple:

SqlQuery1.Sql.Add('CREATE TABLE formations (f_numero INTEGER, f_nom CHARACTER(11))'


);

Pour construire la requête:

• nous pouvons utiliser Add pour ajouter une ligne de requête, Text pour
affecter une requête, Clear pour purger tout texte antérieur, ou
même LoadFromFile pour lire un fichier .txt contenant la requête:

SqlQuery1.Sql.LoadFromFile('cree_formation.txt');

La mise en page n'a aucune importance pour le Serveur: la requête peut être
répartie en plusieurs lignes:

SqlQuery1.Sql.Add('CREATE TABLE');
SqlQuery1.Sql.Add(' formations ');
SqlQuery1.Sql.Add(' (f_numero INTEGER, f_nom CHARACTER(11))');
• nous pouvons entrer la requête en utilisant l'Inspecteur d'Objet. Si nous
cliquons sur Sql, Delphi affiche:

et vous pouvez taper manuellement la requête dans la partie "SQL"

• nous pouvons aussi créer la String en plusieurs étapes par toutes les
primitives de String telles que la concaténation, Insert, le test par Pos ou
autre. Par exemple:

l_requete:= 'CREATE TABLE '+ Edit1.Text+ ' (';


l_requete:= l_requete+ Edit2.Text+ ')';
SqlQuery1.Sql.Add(l_requete);

3.3 - L'application
Pour créer notre table

créez une nouvelle application et appelez-la "p_net_dbx_create_table"

sélectionnez dans la page "dbExpress" de la Palette le composant SqlConnection:


et posez-le sur la tForm
Cliquez deux fois sur SqlConnection1, renseignez "Driver Name", "Connection Name",
"DataBase", "Dialect", "User Name" et "Pass Word"

Sélectionnez la propriété LoginPrompt et basculez sa valeur sur False

Vérifiez la connection en basculant SqlConnection1.Connected sur True, puis fermez la


connection (pour éviter de monopoliser un utilisateur). La connection sera ouverte avant
l'envoi de la requête
sélectionnez dans la page "dbExpress" de la Palette le composant SqlQuery:
sélectionnez sa propriété SqlConnection et initialisez-la à

SqlConnection1
placez un tButton sur la Forme et créez sa méthode OnClick. Placez-y les instructions de
création:

procedure TForm2.create_table_Click(Sender: TObject);


begin
with SqlQuery1 do
begin
Close;

with Sql do
begin
Clear;
Add('CREATE TABLE '+ k_table_name);
Add(' ('
+' f_numero INTEGER,');
Add(' f_nom CHAR(28),');
Add(' f_jours SMALLINT,');
Add(' f_prix NUMERIC(5, 2)');
Add(' )');
end; // with Sql

Try
SqlConnection1.Open;
ExecSql;
display(' ok');
except
on e: Exception do
display(' *** pb_create '+ e.Message);
end;
end; // with SqlQuery1
end; // create_table_Click

compilez, exécutez, et cliquez le bouton

Vous pouvez télécharger le sources du projet "net_dbx_create_table.zip".

3.4 - Vérifier la création


Nous pouvons vérifier que la création a été effectuée en utilisant l'explorateur de
bases de données Delphi, ou en lisant les données ce cette table dans notre
application.

Pour lire les données il suffit d'envoyer la requête

SELECT * FROM formations

au moteur.

Comme les instructions pour envoyer du SQL vers le moteur sont toujours les
mêmes (SqlQuery.Sql.Clear, SqlQuery.Sql.Add, SqlQuery.ExeSql) et que seul le
texte de la requête change, nous avons crée un procédure paramétrée:

procedure execute_sql_request(p_sql_request: String);


begin
with Form2, SqlQuery1 do
begin
Close;

with Sql do
begin
Clear;
Add(p_sql_request);
end; // with Sql

Try
SqlConnection1.Open;
ExecSql;
display(' ok');
except
on e: Exception do
display(' *** pb_create '+ e.Message);
end;
end; // with SqlQuery1
end; // execute_sql_request

Par conséquent, pour vérifier la création de notre table

tapez cette procédure dans votre unité

placez un second tButton sur la Forme et placez-y la requête de lecture:

procedure TForm2.open_table_Click(Sender: TObject);


begin
execute_sql_request('SELECT * FROM '+ k_table_name);
end; // open_table_Click

compilez, exécutez, et cliquez le bouton

Notre requête ouvre la table, mais n'affiche rien: si notre table existe tout se passe
bien, sinon nous aurons une exception. Nous verrons d'ailleurs comment afficher
une Table SELECT en détail plus bas.
3.5 - Effacer une table
Pour supprimer une Table, il faut exécuter la requête:

DROP TABLE formations

Donc:

placez un autre tButton sur la Forme et placez-y la requête de suppression:

procedure TForm2.drop_table_Click(Sender: TObject);


begin
execute_sql_request('DROP TABLE '+ k_table_name);
end; // drop_table_Click

compilez, exécutez, et cliquez le bouton

3.6 - Ajouter des Données


Pour ajouter un enregistrement

3, Interbase Delphi

l'instruction SQL à exécuter est:

INSERT INTO formations


(f_numero, f_nom)
VALUES (3, 'Interbase Delphi')

L'ajout d'enregistrement va modifier les données du Serveur, donc nous


utiliserons tSqlQuery.ExecSql. Par conséquent nous pouvons utiliser notre
procédure générique précédente en lui fournissant cette requête comme paramètre.

De façon détaillée:

placez un tButton sur la Forme et créez sa méthode OnClick. Placez-y les instructions d'ajout:
procedure TForm2.insert_one_Click(Sender: TObject);
begin
execute_sql_request(
'INSERT INTO '+ k_table_name
+ ' (f_numero, f_nom, f_jours, f_prix)'
+ ' VALUES (6, '+ QuotedStr('Asp et Delphi')+ ', 3, 1400.40)')
end; // insert_one_Click

compilez, exécutez, et cliquez le bouton

Nous pouvons aussi paramétrer l'insertion pour ajouter plusieurs lignes plus
facilement:

procedure TForm2.fill_table_Click(Sender: TObject);


// -- insert several hard coded values in a row

procedure insert_generic(p_number: Integer; p_name: String; p_days: Integer; p_cost:


Double);
begin
DecimalSeparator:= '.';
execute_sql_request(
'INSERT INTO '+ k_table_name
+ ' (f_numero, f_nom, f_jours, f_prix)'
+ ' VALUES ('
+ IntToStr(p_number)+ ', '+ QuotedStr(p_name)
+ ', '+ IntToStr(p_days)+ ', '+ FloatToStr(p_cost)+ ')');
DecimalSeparator:= ',';
end; // insert_generic

begin // fill_table_Click
insert_generic(1, 'Initiation Delphi', 3, 1400);
insert_generic(2, 'Bases de Données Delphi', 3, 1400);
insert_generic(3, 'Interbase Delphi', 3, 1400);
insert_generic(4, 'Composants Delphi', 3, 1400);
insert_generic(5, 'UML et Patterns en Delphi', 3, 1400);
insert_generic(6, 'Initiation Pascal', 4, 1900);
end; // fill_table_Click

Vous pouvez télécharger les sources du projet "ib_dbx_insert_data.zip".


4 - Lire et Afficher
4.1 - Principe de dbExpress
Les traitements précédents sont quasiment identiques à ceux que nous effectuons
lorsque nous utilisons les composants IBX:

• SqlConnection a remplacé IbDatabase


• SqlQuery a remplacé IbSql
• les transactions sont gérées automatiquement par dbExpress, au lieu
d'utiliser un IbTransaction explicite

Pour la lecture nous utilisons de même un composant tClientDataset qui,


comme IbQuery stocke les données en mémoire, mais qui possède des propriété
supplémentaires, comme la possiblité de stocker temporairement des données
dans un fichier local indépendant d'Interbase.

La mécanique est la suivante:

• SqlConnection s'occupe de la connexion avec le Client Interbase


• SqlQuery traite les requêtes Sql mais ne tamponne pas les données en
lecture
• le données échangées avec le Serveur utilisent:
o un composent tDataSetProvider qui met les données sous forme de
paquets pour normaliser les échanges avec le Client
o un tClientDataSet qui se charge de tamponner les données
• les tDataSource tDdbGrid usuels se chargent de la visualisation et la saisie

L'organisation des composants est la suivante:


Au niveau fonctionnement:

• lorsque nous ouvrons le tClientDataset, celui-ci propage la demande


au tDatasetProvider, qui la transmet au tSqlQuery.
• le tSqlQuery envoie alors la requête "SELECT ..." au Serveur:

• le Serveur construit l'ensemble des données correspondant à la requête et


renvoie les paquets de lignes vers le Client
dbExpress possède aussi deux extensions:

• il est possible de séparer


o d'une part SqlConnection, SqlQuery et DataSetProvider sur une
machine intermédiaire, placée entre le Serveur et les Clients
o de l'autre les Clients contenant chacun un ClientDataset, et les
composants de contrôle visuel

• Il s'agit alors d'une application 3 niveaux, utilisant pour communiquer entre


le PC du milieu et les Clients des composants de communications. Nous
n'utiliserons pas cette séparation, et laisserons tous les composants sur le
poste Client
• il est possible de travailler sans aucune connexion au Serveur:
le ClientDataSet travaille en mémoire pure, en sauvegardant le contenu de
son cache dans un fichier du Client (à un format binaire ou XML n'ayant rien
à voir avec Interbase). Il s'agit du travail nomade, illustré par ce schéma:

• Ce type de traitement est appelé aussi par Borland "MyBase".

Nous allons nous intéresser dans la suite de cet article aux lectures et
modifications de tables Interbase en utilisant le tClientDataSet.

4.2 - Lecture dans un tClientDataSet


Voici notre première application pour afficher les données:

créez une nouvelle application et nommez-la "p_net_dbx_clientdatase"

sélectionnez dans la page "dbExpress" de la Palette le composant SqlConnection et posez-le sur


la tForm.
Cliquez deux fois sur SqlConnection1, renseignez
"Driver Name" -> Interbase
"Connection Name" -> IbLocal
"DataBase" -> ..\data\institut_pascal_4.gdb
"Dialect" -> 3
"User Name" -> SYSDBA
"Pass Word" -> masterkey
Allez dans l'Inspecteur d'Objet:

• sélectionnez LoginPrompt et basculez sa valeur sur False


• vérifiez la connection en basculant Connected sur True, puis fermez la connection en
basculant Connected sur False.

sélectionnez dans la page "dbExpress" de la Palette le composant SqlQuery et posez-le sur


la tForm.

• Sélectionnez sa propriété SqlConnection et initialisez-la à SqlConnection1


• sélectionnez sa propriété SQL, cliquez sur l'ellipse ... pour ouvrir l'éditeur de chaînes de
caractères et tapez-y la requête:

SELECT * FROM formations_4

• cliquez sur "OK" pour ferme l'éditeur

sélectionnez dans la page "Data Access" de la Palette le composant DatasetProvider:


• Posez-le sur la tForm.
• dans sa propriété DataSet sélectionnez SqlQuery1

sélectionnez dans la page "Data Access" de la Palette le composant ClientDataSet:


• Posez-le sur la tForm.
• dans sa propriété ProviderName sélectionnez DatasetProvider1

sélectionnez dans la page "Data Access" de la Palette le composant DataSource:


• Posez-le sur la tForm.
• dans sa propriété DataSet sélectionnez ClientDataSet1

sélectionnez dans la page "Data Controls" de la Palette le composant dbGrid:


• Posez-le sur la tForm.
• dans sa propriété DataSource sélectionnez DataSource1

sélectionnez sur la Forme SqlClientDataSet1, et basculez sa propriété Active à True

dbExpress envoie la demande d'ouverture à DataSetProvider1, qui la transmet à SqlQuery1, qui


connecte la base, recherche les données et les propage par le chemin inverse dans la dbGrid:
vous voyez les donnée affichées:
Notez l'ordre de chaînage des composants:

Cet ordre provient des multiplicités possibles:

• une tSqlConnection peut être reliée à plusieurs tSqlQueries


• un tSqlQuery peut être relié à plusieurs tDatasetProviders
• un tDataSetProvider peut alimenter plusieurs tClientDatasets
• un tClientDataSet peut être relié à plusieurs tDataSource
• un tDataSource peut être relié à plusieurs composants visuels tels que
la tdbGrid
Si Delphi avait proposé au développeur programmeur de relier tSqlConnection à
ses tSqlQueries, il aurait fallu prévoir une LISTE de tSqlQueries associés, alors que
dans l'ordre inverse, chaque tSqlQuery ne peut avoir qu'une tSqlConnection, donc
une seule ligne dans l'Inspecteur d'Objet.

Vous pouvez télécharger le sources du projet "p_net_dbx_clientdatase.zip".

5 - Le mode nomade
5.1 - Principe
Nous pouvons sauvegarder les données stockées dans un tClientDataset dans un
fichier disque, dans un format .XML ou un format binaire équivalent. Pour cela, il
suffit d'appeler

tClientDataset.SaveToFile(nom_fichier);

Ces données peuvent ensuite être rechargées par l'instruction symétrique:

tClientDataset.LoadFromFile(nom_fichier);

Bien plus intéressant encore, les modifications apportées aux données, que celles-ci
proviennent d'un chargement depuis le Serveur ou depuis un fichier local, sont
sauvegardées en mémoire, et mémorisées sur disque. Pour modifier les données
du Serveur, il suffit d'appeler:

tClientDataset.ApplyUpdates(nombre_erreurs);
5.2 - La sauvegarde
Commençons par présenter la sauvegarde:
dans l'application précédente, posez un autre tButton sur la Forme, nommez-le "save_cds_" et
placez-y l'instruction de sauvegarde:

const k_save_dataset_name= '..\_data\save_formation.xml';

procedure TForm2.save_to_file_Click(Sender: TObject);


begin
ClientDataset1.SaveToFile(k_save_dataset_name);
end; // save_to_file_Click

5.3 - Le chargement
Pour bien démontrer que le travail en mode nomade ne nécessite aucune
connexion, nous allons construire une nouvelle application qui charge, modifie, et
sauve les données, sans aucun lien avec le Serveur Interbase. Un peu comme un
commercial qui, après avoir sauvegardé le matin les données de ses clients sur son
portable, va récupérer les commandes chez ses clients durant la journée.

Pour cela:

créez une nouvelle application et appelez-la "p_net_dbx_clientdataset"

sélectionnez dans la page "Data Access" de la Palette le composant ClientDataSet et posez-le


sur la tForm.

sélectionnez dans la page "Data Access" de la Palette le composant DataSource:

• Posez-le sur la tForm.


• dans sa propriété DataSet sélectionnez ClientDataSet1

sélectionnez dans la page "Data Controls" de la Palette le composant dbGrid:

• Posez-le sur la tForm.


• dans sa propriété DataSource sélectionnez DataSource1

dans l'application précédente, posez un autre tButton sur la Forme, nommez-le "load_cds_" et
placez-y l'instruction de chargement:

const k_save_dataset_name= '..\_data\save_formation.xml';

procedure TForm2.load_cds_Click(Sender: TObject);


begin
ClientDataset1.LoadFromFile(k_save_dataset_name);
end; // load_cds_Click
compilez et exécutez. Cliquez sur le bouton: les données sont chargées depuis le fichier:

5.4 - affichage .XML


Nous souhaitons, à titre de vérification, pouvoir examiner le contenu du fichier
.XML. Nous avons pour cela crée une classe Delphi qui analyse le fichier et en
extrait les données. Cette classe a été présenté dans
l'article display ClientDataset .XML. Nous l'avons simplement aménagée
pour Delphi 8:

• utilisation des unités _net_ pour l'affichage


• remplacement des FILE par des tFileStream.

Le reste étant identique, nous ne ferons que l'utiliser ici. Pour cela:
ajoutez l'importation des unités u_c_net_cds_table et u_c_net_cds_analyze_cds

posez un autre tButton sur la Forme, nommez-le "display_xml_" et placez-y l'instruction


d'affichage du fichier .XML:

uses u_c_net_display, u_c_net_log


, u_c_net_text_buffer
, u_c_net_cds_analyze_xml
, u_c_net_cds_table
;

procedure TForm2.display_xml_Click(Sender: TObject);


var l_c_table: c_table;
begin
with c_cds_analyze_xml.create_cds_analyze_xml('xml', k_save_dataset_name) do
begin
l_c_table:= c_table.create_table('table');
analyze_xml(l_c_table);

display_line;
l_c_table.display_formatted_line_list;
l_c_table.Free;
Free;
end; // with c_analyze_xml
end; // display_xml_Click

compilez et exécutez. Cliquez sur le bouton: les données du fichier .XML sont affichées
dans Memo1:

5.5 - Modifications
Pour pouvoir sauvegarder les modifications effectuées en mode nomade, il faut
aussi pouvoir sauvegarder:
dans l'application précédente, posez un autre tButton sur la Forme, nommez-le "save_cds_" et
placez-y l'instruction de sauvegarde, comme pour la précédente application:

const k_save_dataset_name= '..\_data\save_formation.xml';

procedure TForm2.save_to_file_Click(Sender: TObject);


begin
ClientDataset1.SaveToFile(k_save_dataset_name);
end; // save_to_file_Click

Nous allons maintenant modifier le contenu de notre ClientDataset:

lancez l'applications
chargez le fichier .XML

modifiez la première ligne. Par exemple:

changez de ligne (pour poster le changement)

sauvegardez en cliquant "save_cds_"

Nous pouvons vérifier le nouveau contenu du fichier .XML:


cliquez "display_xml_":

Nous voyons que le fichier .XML conserve:

• l'ancienne ligne ("Asp et Delphi")


• la ligne modifiée ("Delphi 8 Asp.Net")
Cette sauvegarde dans le fichier .XML permet

• la restauration des états antérieurs si nous le souhaitons


• la mise à jour en envoyant vers le serveur du changement entre la version
initiale et la dernière mise à jour

Nous aurions de même des enregistrements additionnels si nous ajoutons des


données ou si nous supprimons des lignes.

Voyons donc comment notre brave VRP va mettre à jour


le Serveur Interbase lorsqu'il rentrera le soir au bureau.

6 - Mise à jour du Serveur Interbase


6.1 - Principe
Les modifications, qu'elles soient effectuées en direct à
un tClientDataset connecté au Serveur (via tDatasetProvider etc) ou qu'elles
proviennent du chargement d'un fichier local .XML sont envoyées vers
le Serveur par tClientDataset.ApplyUpdates.

6.2 - ApplyUpdates
Voici une application qui effectue cette mise à jour.

Installons d'abord la chaîne allant du tSqlConnection au tDbGrid:

créez une nouvelle application et nommez-la "p_net_dbx_apply_updates"

sélectionnez dans la page "dbExpress" de la Palette le composant SqlConnection et posez-le sur


la tForm.
Cliquez deux fois sur SqlConnection1, renseignez
"Driver Name" -> Interbase
"Connection Name" -> IbLocal
"DataBase" -> ..\data\institut_pascal_4.gdb
"Dialect" -> 3
"User Name" -> SYSDBA
"Pass Word" -> masterkey
Allez dans l'Inspecteur d'Objet:

• sélectionnez LoginPrompt et basculez sa valeur sur False


• vérifiez la connection en basculant Connected sur True, puis fermez la connection en
basculant Connected sur False.
sélectionnez dans la page "dbExpress" de la Palette le composant SqlQuery et posez-le sur
la tForm.

• Sélectionnez sa propriété SqlConnection et initialisez-la à SqlConnection1


• sélectionnez sa propriété SQL, cliquez sur l'ellipse ... pour ouvrir l'éditeur de chaînes de
caractères et tapez-y la requête:

SELECT * FROM formations_4

• cliquez sur "OK" pour ferme l'éditeur

sélectionnez dans la page "Data Access" de la Palette le composant DatasetProvider. Posez-le


sur la tForm et dans sa propriété DataSet sélectionnez SqlQuery1

sélectionnez dans la page "Data Access" de la Palette le composant ClientDataSet, posez-le sur
la tForm et dans sa propriété ProviderName sélectionnez DatasetProvider1

sélectionnez dans la page "Data Access" de la Palette le composant DataSource, posez-le sur
la tForm et dans sa propriété DataSet sélectionnez ClientDataSet1

sélectionnez dans la page "Data Controls" de la Palette le composant dbGrid, posez-le sur
la tForm et dans sa propriété DataSource sélectionnez DataSource1

Puis

posez un tButton sur la Forme, nommez-le "load_cds_" et placez-y l'instruction de chargement:

ClientDataset1.LoadFromFile(k_save_dataset_name);
posez un tButton sur la Forme, nommez-le "apply_updates_", et tapez le code qui envoient les
modifications vers le Serveur:

procedure TForm2.apply_updates_Click(Sender: TObject);


var l_error_count: Integer;
begin
l_error_count:= ClientDataset1.ApplyUpdates(-1);
end; // apply_updates_Click

Pour surveiller ce qui va se passer, nous allons afficher les


instructions Sql échangées en utilisant un composant SqlMonitor:

sélectionnez dans la page "dbExpress" de la Palette le composant SqlMonitor:


• posez-le sur la tForm.
• sélectionnez sa propriété SqlConnection et initialisez-la à SqlConnection1
• sélectionnez sa propriété Active et basculez la sur True
• créez son événement OnLogTrace et affichez dans Memo1 les traces Sql:

var g_trace_count: Integer= 0;

procedure TForm2.SQLMonitor1LogTrace(Sender: TObject;


var CBInfo: SQLTRACEDesc);
begin
with SQLMonitor1, TraceList do
while g_trace_count< Count do
begin
display(Strings[g_trace_count]);
Inc(g_trace_count);
end;
end; // SQLMonitor1LogTrace

Et finalement pour détecter les erreurs que ApplyUpdates pourrait provoquer, nous
demandons à notre application de surveiller la mise à jour:
sélectionnez ClientDataset1

créez son événement OnReconcileError

affichez dans Memo1 tout message d'erreur:

procedure TForm2.ClientDataSet1ReconcileError(
DataSet: TCustomClientDataSet; E: EReconcileError;
UpdateKind: TUpdateKind; var Action: TReconcileAction);
begin
display('reconcile '+ e.Message);
end; // ClientDataSet1ReconcileError

A présent, en avant:

compilez et exécutez

cliquez "load_cds_"

l'application charge le fichier .XML

cliquez "apply_updates_"

Delphi envoie les changements vers les Serveur

• nous voyons dans le Memo les primitives "isc_xxx" de l'API Interbase


• le code d'erreur retourné par ApplyUpdates et 0
Vous pouvez d'ailleurs vous assurer que le Serveur a bien tenu compte des
modifications en fermant l'application et en la relançant: "open_cds_" récupèrera
bien les valeurs modifiées.

Nous n'avons pas traité ici la gestion des erreurs (essentiellement ce qui se passe si
quelqu'un d'autre a modifié les données avant nous) ou si nous souhaitons affiner
les règles de mise à jour. Voyez l'articles sur Interbase dbExpress à ce sujet

7 - Télécharger les Exemples


Voici les programmes de cet article:

• net_dbx_create_table.zip : création de table (13 K)


• net_dbx_briefcase_clientdataset.zip : le mode nomade (23 K)
• net_dbx_clientdataset.zip : utilisation de tClientDataset (13 K)
• net_dbx_apply_updates.zip : modification de données avec réconciliation
(13 K)
Ces .ZIP comprennent:

• le .DPR, la forme principale, les formes annexes eventuelles


• les fichiers de paramètres (le schéma et le batch de création)
• dans chaque .ZIP, toutes les librairies nécessaires à chaque projet (chaque
.ZIP est autonaume)

Ces .ZIP contiennent des chemins RELATIFS. Par conséquent:

• créez un répertoire n'importe où sur votre machine


• placez le .ZIP dans ce répertoire
• dézippez et les sous-répertoires nécessaires seront crées
• compilez et exécutez

Ces .ZIP ne modifient pas votre PC (pas de changement de la Base de Registre, de


DLL ou autre). Pour supprimer le projet, effacez le répertoire.

Comme d'habitude:

• nous vous remercions de nous signaler toute erreur, inexactitude ou


problème de téléchargement en envoyant un e-mail
à jcolibri@jcolibri.com. Les corrections qui en résulteront pourront aider les
prochains lecteurs
• tous vos commentaires, remarques, questions, critiques, suggestion
d'article, ou mentions d'autres sources sur le même sujet seront de même
les bienvenus à jcolibri@jcolibri.com.
• plus simplement, vous pouvez taper (anonymement ou en fournissant votre
e-mail pour une réponse) vos commentaires ci-dessus et nous les envoyer
en cliquant "envoyer" :

Nom :
E-mail :

Commentaires * :

• et si vous avez apprécié cet article, faites connaître notre site, ajoutez un
lien dans vos listes de liens ou citez-nous dans vos blogs ou réponses sur
les messageries. C'est très simple: plus nous aurons de visiteurs et de
références Google, plus nous écrirons d'articles.
8 - Conclusion
Lors de cette présentation de dbExpress, nous avons indiqué comment
installer Interbase, créer une base, des tables, ajouter, lire, modifier et effacer des
données.

Si vous avez des questions, vous pouvez:

• vous reporter au livre Delphi dBase qui présente, par le détail, la gestion
des composants visuels et les techniques de traitement des données
(formatage, vérfications, calculs...)
• pour les blobs, voyez Blobs Interbase
• pour l'utilisation d'Interbase en mode Client Serveur, sans utiliser le BDE,
voyez le Tutorial Interbase
• l'affichage du contenu d'un fichier .XML correspondant à la sauvegarde
locale d'un tClientDataset est présenté dans Affichage ClientDataset XML
• la présentation Architecture du Moteur Interbase présente l'organisation
du programme Interbase, correspondant aux sources fournies
par Borland pour la version 6.
• je présenterai à la conférence Borcon France 2004 le panorama des
techniques d'accès aux données Interbase: les API isc,
le BDE, Interbase Express, dbExpress, et pour Delphi 8, IBX.NET en
mode VCL.NET et ADO.NET en mode Windows Forms.
• vous pouvez aussi m'adresser vos questions par e-mail
à jcolibri@jcolibri.com

Nous n'avons pas essayé d'être exhaustif dans la présentation. Lors des stages que
j'anime personnellement à l'Institut Pascal, j'entre beaucoup plus dans le détail:

• la gestion des multiples erreurs et exceptions qui interviennent lors


d'applications utilisant des bases de données
• les possibilités d'installer Interbase depuis Delphi, et d'interroger les
paramètres de la Base ou du schéma depuis un programme Delphi, de lister
les tables, les champs etc
• le traitement des contraintes (clé primaires, intégrité référentielle, intégrité
sémantique)
• la manipulation détaillée des valeurs extraite d'une Table, en utilisant
les tFields et les différents composants visuels tDb_xxx, ainsi que les
traitements spécifiques aux chaînes, aux dates, aux blobs
• les techniques de validation de saisie essentielles pour toute application de
gestion
• le traitement spécifiques à dbExpress:
o l'utilisation de tClientDataset avec ses multiples possibilités
o les paramétrage du tDatasetProvider
o la gestion des erreurs de réconciliation et le traitement d'utilisateurs
multiples
• l'étude approfondie du langage SQL, qui est au coeur de tout traitement
avec des Serveurs Sql
• les triggers, les procédures cataloguées (tStoredProc), les générateurs
• la gestion de Serveur (sauvegarde / restauration, statistiques, réglage)

Pour examiner le programme détaillé de cette formation, cliquez Client Serveur


Interbase. Nous proposons de plus d'autres formations présentées dans ces pages
(programme, dates des prochaines sessions, conditions, transparents,
abonnement à la lettre d'information...).

Finalement j'interviens aussi pour des missions d'audit, de réalisation de projet, de


portage et maintenance, et de tutorat.

Vous aimerez peut-être aussi