I. Introduction▲
Que ce soit à cause d'une contrainte exigée par un client ou bien par choix, il peut vous arriver, un jour, de devoir développer une application .NET travaillant avec Oracle.
Comme toutes les autres bases de données que vous pouvez utiliser sous .NET, vous avez plusieurs moyens pour les joindre :
- Via ODBC: méthode « universelle » de connexion à une base de données. Cette technique fonctionne toujours, mais ne vous garantit pas les meilleurs résultats ;
- Via un provider intégré au framework .NET: bien qu'efficace, cette technique peut ne pas vous satisfaire si vous cherchez à avoir des performances optimales ;
- Via un provider dédié: qu'il soit créé par la société qui a créé la base de données, ou par une autre société, préférez toujours ce type de provider. En effet, conçus exclusivement pour cette base, ils vous permettront d'avoir les meilleurs résultats possibles.
Dans le cas d'Oracle, nous utiliseront ODP (Oracle Data Provider), le fournisseur d'accès aux données (Provider) de la base Oracle, et qui a été réalisé par cette même société.
II. Oracle Data Provider▲
II-A. Téléchargement▲
ODP peut être téléchargé depuis le site d'Oracle : www.oracle.com.
Le lien direct vers le téléchargement est : http://www.oracle.com/technology/software/tech/windows/odpnet/utilsoft.html.
Une inscription (gratuite) est nécessaire pour avoir accès au téléchargement.
Sur cette page, vous aurez la possibilité de télécharger deux providers:
- Oracle10g Data Provider for .NET 10.1.0.3.01 including ODAC: il s'agit du provider nécessaire, dans le cas où vous utiliseriez une base de données Oracle 10g
- Oracle9i Release 2 Data Provider for .NET 9.2.0.4.0 including ODAC: cette version du provider est à prendre si votre base de données est une base Oracle 9i
Téléchargez le provider adapté à votre base de données (dans mon cas, il s'agit du deuxième), puis passez ensuite à l'installation.
II-B. Installation▲
Une fois le provider téléchargé, vous vous retrouvez avec un fichier exécutable (.exe) sur lequel vous double-cliquez: les fichiers sont alors décompressés dans un répertoire nommé Disk1.
Pour lancer l'installation du provider, il ne vous reste plus qu'a exécuter le fichier Disk1\setup.exe. Vous vous retrouvez alors devant l'Oracle Universal Installer, qui vous permet d'installer les produits Oracle :
L'écran suivant vous demande ensuite de spécifier les différents chemins d'installation : à moins de savoir exactement ce que vous faîtes, laissez les valeurs par défaut et cliquez sur « Suivant ».
La liste des produits qu'il est possible d'installer apparaît : nous sommes intéressé par ODP, donc, choisissez la première ligne (dans mon cas « Oracle Data Provider for .NET 9.2.0.4.01 »), puis cliquez une nouvelle fois sur « Suivant »
Un écran récapitulatif apparaît et un clic sur « Installer » permet de lancer l'installation du provider.
Si l'installation s'est bien déroulée, vous devriez voir cet écran :
À ce moment là, cliquez sur le bouton « Quitter » pour sortir de l'installeur. Votre installation est terminée !
Vous pouvez, si vous le souhaitez, supprimer le répertoire Disk1 et le fichier que vous avez téléchargé: ceux-ci ne sont plus nécessaires.
Voyons maintenant comment utiliser ce provider dans votre code .NET.
III. Oracle et .NET▲
III-A. Ajout des références▲
Avant de pouvoir utiliser votre provider, vous devez ajouter une référence à votre projet.
Pour cela, faîtes un clic droit, dans l'explorateur de solution, sur les références, puis choisissez « Ajouter une référence ».
Dans l'écran qui apparaît, descendez jusqu'a voir puis sélectionner la référence Oracle.DataAccess.
Une fois la référence ajoutée, pensez également à faire le using (en C#) ou Import (en VB.NET) correspondant :
//
Ajout
du
using
pour
utiliser
les
objets
Oracle
using
Oracle.
DataAccess.
Client;
Vous êtes maintenant prêt à vous connecter à votre base Oracle et à y effectuer des requêtes SQL, depuis votre programme .NET.
III-B. Création de la connexion▲
La première chose que vous devez faire, c'est initialiser l'objet qui va effectuer la connexion à la base Oracle.
Pour cela, vous disposez de l'objet OracleConnection, qui peut prendre un paramètre, qui est la chaîne de connexion.
Si vous ne passez pas la chaîne de connexion au constructeur de votre objet OracleConnection, vous devrez la spécifier au moyen de la propriété ConnectionString.
Si vous ne connaissez pas le format de la chaîne de connexion, regardez sur ce site : http://www.connectionstrings.com/
Une fois la chaîne de connexion connue, il ne vous reste plus qu'à l'utiliser dans votre code:
private
OracleConnection OConnexion =
new
OracleConnection
(
);
OConnexion.
ConnectionString =
"
Data
Source
=
lab
;
User
Id
=
Scott
;
Password
=
Tiger
;
"
;
Voyons maintenant comment ouvrir et fermer cette connexion.
III-C. Ouverture/Fermeture de la connexion▲
De la même façon que vous le feriez avec une autre base de données, vous devez simplement appeler les méthodes Open et Close de votre objet OracleConnection.
Soit :
//
Ouverture
de
la
connexion
OConnexion.
Open
(
);
et
//
Fermeture
de
la
connexion
OConnexion.
Close
(
);
//
Libération
des
ressources
OConnexion.
Dispose
(
);
Maintenant que vous savez ouvrir et fermer une connexion au serveur Oracle, voyons comment nous pouvons envoyer des requêtes SQL.
III-D. Exécuter une requête SQL▲
Pour exécuter une requête SQL, vous devez utiliser l'objet OracleCommand, qui prend en paramètre :
- la requête à exécuter ;
- la référence vers la connexion sur laquelle travailler (bien que cet élément puisse être spécifié ultérieurement, au moyen de la propriété Connection).
Il vous est également possible de définir la propriété CommandType, pour spécifier si vous allez utiliser une procédure stockée ou une simple requête SQL.
Ce qui donne, par exemple :
//
Requête
SQL
a
exécuter
string
sQuery =
"
SELECT
ename
,
empno
from
emp
"
;
//
Instanciation
de
l'objet
OracleCommand
et
de
ses
propriétés
OracleCommand cmd =
new
OracleCommand
(
sQuery);
cmd.
Connection =
OConnexion;
cmd.
CommandType =
CommandType.
Text;
Ensuite, il ne vous reste plus qu'a appeler l'une des méthodes servant à l'exécution de votre requête.
Hormis les méthodes habituelles (ExecuteNonQuery, ExecuteReader, ExecuteScalar et ExecuteXmlReader), il existe deux autres méthodes également disponibles :
- ExecuteStream: exécute une requête SQL et retourne le résultat dans un objet de type Stream ;
- ExecuteToStream: exécute une requête SQL et ajoute le résultat (en tant que document XML) aux flux de type Stream passé en paramètre.
Attention donc à bien utiliser la méthode dont vous avez besoin (par exemple, ExecuteReader si vous avez besoin de lire des résultats, ExecuteScalar si votre requête ne renvoi qu'un seul résultat, etc.)
III-E. Lecture des enregistrements▲
Lire les enregistrements retournés par une requête SQL n'est pas plus compliqué à faire : il vous suffit juste d'utiliser le bon objet, à savoir un OracleDataReader.
Un bout de code étant souvent plus parlant qu'un long discours, voyons ce que cela signifie :
//
On
instancie
notre
OracleDataReader
OracleDataReader reader =
cmd.
ExecuteReader
(
);
//
Tant
qu'il
y
a
des
résultats
à
lire,
on
les
affiche
while
(
reader.
Read
(
) )
{
//
On
affiche
le
nom
et
le
numéro
MessageBox.
Show
(
"
Nom
:
"
+
reader.
GetString
(
0
));
MessageBox.
Show
(
"
Numéro
:
"
+
reader.
GetInt32
(
1
));
}
L'exécution de ce code produit l'affichage des résultats de la requête SQL (dans notre cas, elle affiche le nom et le numéro des employés).
III-F. Exécuter une transaction▲
Vous devez savoir que tout ordre SQL du DML (Data Manipulation Language), c'est-à-dire tout ordre de type INSERT, UPDATE et DELETE est une transaction.
Une transaction peut-être validée, au moyen du mot-clé COMMIT, ou bien elle peut-être annulée, grâce à ROLLBACK.
En .NET (et grâce à l'ODP), vous avez la possibilité de gérer ces transactions au moyen de l'objet OracleTransaction, objet qui vous est renvoyé grâce à la méthode BeginTransaction de l'objet OracleConnection.
Voyons cela en exemple :
//
Récupération
de
l'objet
OracleTransaction
:
Début
de
la
transaction
OracleTransaction trans =
OConnexion.
BeginTransaction
(
);
string
sQuery2 =
"
INSERT
INTO
emp
(
ename
,
empno
)
VALUES
(
'
Tom
'
,
100
)
"
;
OracleCommand cmd2 =
new
OracleCommand
(
sQuery2,
OConnexion);
cmd2.
CommandType =
CommandType.
Text;
cmd2.
Transaction =
trans;
try
{
//
Exécution
de
la
requête
cmd2.
ExecuteNonQuery
(
);
//
On
soumet
la
requête
au
serveur:
tout
s'est
bien
déroulé
,
la
requête
est
exécutée
trans.
Commit
(
);
MessageBox.
Show
(
"
Insertion
effectuée
avec
succès
"
);
}
catch
(
Exception ex)
{
//
Une
erreur
est
survenue:
on
ne
valide
pas
la
requête
trans.
Rollback
(
);
MessageBox.
Show
(
"
Insertion
non
effectuée
!
!
\n
Erreur
:
"
+
ex.
Message);
}
finally
{
//
Libération
des
ressources
cmd2.
Dispose
(
);
}
L'appel à la méthode Commit vous permet de valider les transactions, c'est-à-dire de rendre permanent les changements effectués.
À l'inverse, la méthode RollBack vous donne la possibilité d'annuler ces changements.
Vous pouvez trouver plus d'informations sur ces termes dans le glossaire de http://www.developpez.com.
Vous pouvez également utiliser des CheckPoint, qui représentent le point de contrôle qui sera atteint, dans le cas où vous effectuez un RollBack.
Pour cela, vous devez spécifier, comme argument de la méthode RollBack, le nom du CheckPoint que vous voulez joindre, c'est-à-dire :
//
Récupération
de
l'objet
OracleTransaction
:
Début
de
la
transaction
OracleTransaction trans =
OConnexion.
BeginTransaction
(
);
string
sQuery2 =
"
INSERT
INTO
emp
(
ename
,
empno
)
VALUES
(
'
Tom
'
,
100
)
"
;
OracleCommand cmd2 =
new
OracleCommand
(
sQuery2,
OConnexion);
cmd2.
CommandType =
CommandType.
Text;
cmd2.
Transaction =
trans;
//
Exécution
de
la
requête
cmd2.
ExecuteNonQuery
(
);
//
Création
d'un
CheckPoint,
point
de
contrôle
trans.
Save
(
"
MonCheckPoint
"
);
//
On
définit
l'autre
requête
à
exécuter
cmd2.
CommandText =
"
INSERT
INTO
emp
(
ename
,
empno
)
VALUES
(
'
Tom1
'
,
101
)
"
;
//
Exécution
de
la
requête
cmd2.
ExecuteNonQuery
(
);
//
On
fait
un
retour
arrière
sur
le
CheckPoint
MonCheckPoint
RollBack
(
"
MonCheckPoint
"
);
//
On
fait
le
Commit.
//
Comme
nous
avons
fait
un
RollBack
sur
un
checkpoint
//
seul
la
première
requête
sera
validée
sur
le
serveur
trans.
Commit
(
);
//
Libération
des
ressources
cmd2.
Dispose
(
);
III-G. Obtenir des informations sur la session Oracle▲
Il vous est possible d'obtenir diverses informations (telle que la langue, le format de date, etc.) sur la session en cours, au moyen de l'objet OracleGlobalization.
Celui-ci s'obtient grâce à la méthode GetThreadInfo.
Par exemple :
//
On
récupère
l'objet
OracleGlobalization
OracleGlobalization glob =
OracleGlobalization.
GetThreadInfo
(
);
MessageBox.
Show
(
"
Langue
de
la
session
:
"
+
glob.
Language);
MessageBox.
Show
(
"
Timezone
de
la
session
:
"
+
glob.
TimeZone);
Bien entendu, il existe un grand nombre de paramètres que vous pouvez récupérer: je vous laisse le soin de les découvrir plus en détails.
Vous avez également la possibilité de modifier ces informations, au moyen de la méthode SetThreadInfo :
//
Modification
des
paramètres
glob.
Language =
"
FRENCH
"
;
OracleGlobalization.
SetThreadInfo
(
glob);
III-H. Les requêtes paramétrées▲
Il vous est tout à fait possible d'utiliser les requêtes paramétrées (plus rapide et plus efficace que les simples requêtes SQL) avec l'ODP et .NET.
Pour cela, vous devez utiliser l'objet OracleParameter, qui représente un paramètre pour un objet OracleCommand.
//
Attention
au
signe
pour
les
requêtes
paramétrées
sous
Oracle
string
sQuery3 =
"
INSERT
INTO
emp
(
ename
,
empno
)
VALUES
(
:
1
,
:
2
)
"
;
OracleCommand cmd3 =
new
OracleCommand
(
sQuery3,
OConnexion);
cmd2.
CommandType =
CommandType.
Text;
//
On
définit
la
liste
des
paramètres
OracleParameter ename_param =
new
OracleParameter
(
"
ename_param
"
,
OracleDbType.
Varchar2,
ParameterDirection.
Input);
ename_param.
Value =
"
Toto
"
;
OracleParameter empno_param =
new
OracleParameter
(
"
empno_param
"
,
OracleDbType.
Decimal,
ParameterDirection.
Input);
ename_param.
Value =
200
;
//
On
ajoute
cette
liste
de
paramètre
à
l'objet
OracleCommand
cmd3
cmd3.
Parameters.
Add
(
ename_param);
cmd3.
Parameters.
Add
(
empno_param);
//
On
exécute
la
requête
cmd3.
ExecuteNonQuery
(
);
//
Libération
des
ressources
cmd3.
Dispose
(
);
Le paramètre ParameterDirection.Input vous permet de spécifier que vous attendez un paramètre en entrée.
À l'inverse, ParameterDirection.Output signifie que vous être prêt à recevoir un paramètre retourné par le serveur (par exemple, dans le cas où une procédure stockée doit vous renvoyer une valeur).
IV. Conclusions▲
Comme nous l'avons vu, travailler avec Oracle en .NET ne présente aucune difficulté grâce à l'Oracle Data Provider. Si vous êtes habitué à travailler sous SQL Server (et donc à utiliser les objets de type Sql*), vous ne serez nullement dépaysé par ce changement de SGBD.
Bien entendu, gardez tout de même à l'esprit que cet article ne couvre pas tout les possibilités offertes par l'ODP: je vous laisse le soin d'en faire le tour complet.
V. Liens▲
Le site Internet d'Oracle : www.oracle.com/.
Le lien pour télécharger le provider : http://www.oracle.com/technology/software/tech/windows/odpnet/utilsoft.html.
Quelques articles sur .NET et Oracle : http://www.oracle.com/technology/community/greatest_hits/2004.html.
La page .NET sur Oracle.com : La page .NET sur Oracle.com.
La FAQ ODP : La FAQ ODP.
VI. Téléchargements▲
Solution contenant le programme utilisé pour écrire l'article : Solution