Remerciements▲
L'auteur de cet article est John Paul Cook, je tiens à le remercier chaleureusement, ainsi que Justin Kestelyn, rédacteur en chef d'OTN, de m'avoir autorisé à traduire cet article.
Merci à Didier Danse, à David Pédehourcq, à Ronald Vasseur, et à neguib pour leurs relectures.
I. Introduction▲
Grâce à la popularité croissante rencontrée par le framework .NET de Microsoft, beaucoup de développeurs sont intéressés par des articles détaillant les meilleurs moyens d'intégrer une application .Net avec Oracle - pas seulement en termes de connectivité basique, mais également en termes d'efficacité et de performances du développement sous Visual Studio .Net (VS.NET).
Dans cet article, nous allons aborder les mécanismes basiques, mais néanmoins essentiels, à mettre en œuvre dans la conception d'une application .Net connectée à une base Oracle, parmi lesquels :
- comment ajouter à votre projet des références vous permettant d'inclure les modules de classes Oracle ;
- comment créer des chaînes de connexion Oracle ;
- comment travailler avec les objets Connection, Command, et DataReader.
Vous aurez l'occasion de mettre en pratique ce que vous apprendrez à l'aide de trois petits praticiels (relativements simples).
Vous trouverez des informations et des praticiels à propos de la sécurisation de votre application dans l'article suivant :
Securing a .NET Application on the Oracle Database.
Voyez également la série complète :
Mastering .NET Application Development with Oracle pour des articles techniques couvrant une large gamme de solutions concernant différentes phases du développement d'une application.
Pour information, sachez que ODT (Oracle Developper Tool) pour .Net est gratuit et téléchargeable à partir d'OTN.
Cet utilitaire permet d'ajouter une extension à Visual Studio qui rend le développement de la couche d'accès aux données plus facile et plus intuitif. Le but de cet article n'étant pas de rentrer dans les détails de son fonctionnement, je vous renvoie au Product Center correspondant pour plus d'informations.
II. Les fournisseurs de données .NET (.Net Data Provider)▲
En plus d'une interface basique de connexion cliente, une application .Net requiert un fournisseur de données managé (« managé » signifiant ici compilé spécialement pour l'architecture .Net). Le fournisseur de données est la couche entre le code de l'application .Net et le logiciel de connectivité du client Oracle. En général, on obtient de meilleures performances en utilisant un fournisseur optimisé pour un SGBD en particulier plutôt qu'en utilisant le fournisseur de données générique OLE DB.
Oracle, Microsoft ainsi que d'autres intégrateurs proposent des fournisseurs de données optimisés pour Oracle. Oracle et Microsoft mettent le leur à disposition gratuitement. Le fournisseur de Microsoft de la version 1.1 du Framework .Net est même directement inclus dans ce Framework, aucun autre téléchargement n'étant nécessaire. Les fournisseurs de certains intégrateurs sont compatibles avec d'anciennes versions d'Oracle, ou ne nécessitent pas l'installation du client Oracle.
Dans cet article, nous utiliserons le Oracle Data Provider for .NET (ODP.NET), disponible ici.
À partir du moment où ODP.NET et le client Oracle sont installés, le développement d'applications Visual Studio .Net peut commencer. Il est conseillé de vérifier la connexion avant de démarrer. Si à partir de la machine où se trouve Visual Studio, vous pouvez vous connecter à Oracle via SQL*Plus, c'est que l'installation et la configuration de votre client Oracle sont correctes.
Si vous débutez avec Oracle, vous pouvez vous reporter à la section « Connecting to the Oracle Database » accessible à partir du lien suivant :
Oracle Data Provider for .NET Developer's Guide 10g si vous recherchez des informations spécifiques, ou à partir de ce lien :
Oracle Database Administrator's Guide 10g pour des informations à propos de la gestion d'une base Oracle en général.
Vous pouvez également consulter le document pratique :
Connect to an Oracle Database Using ODP.NET (documentation avec de nombreux exemples de code).
III. Créer un nouveau projet dans Visual Studio.NET▲
Démarrons Visual Studio pour créer un projet en cliquant sur le menu suivant :
Une fenêtre Nouveau Projet apparaît alors. Choisissez alors le langage de votre choix dans la partie gauche (Types de Projets) : ici, c'est VB.Net qui est sélectionné. Dans la partie droite (Modèles), il nous faut choisir un modèle de projet. Nous choisirons le modèle de base Windows Application, simple et adapté à notre leçon.
Vous choisirez de préférence des noms significatifs pour baptiser vos projets (ici : OraWinApp) et vos solutions (ici : OraSamples). Une solution peut englober un ou plusieurs projets. Si une solution n'est composée que d'un projet, il est courant de leur donner le même nom.
III-A. Ajout d'une référence▲
Comme notre projet a pour vocation à se connecter à une BDD Oracle, il est nécessaire d'ajouter la référence contenant le fournisseur de données adéquat. Grâce à l'explorateur de solution, sélectionnez le nœud Références, cliquez droit dessus et cliquez sur Ajouter une Référence. Une autre solution consiste à passer par le menu Projet -> Ajouter une Référence.
La fenêtre Ajouter une référence apparaît :
Dans la liste de composants proposés, sélectionnez la bibliothèque Oracle.DataAccess.dll, cliquez sur le bouton Sélectionner, puis sur OK : le fournisseur de données est maintenant reconnu dans notre projet :
III-B. Déclarations VB.NET/C#▲
Suite à l'ajout de notre référence, il est d'usage d'ajouter les déclarations Imports en VB.Net, using en C# ou import en J#. Techniquement, ces déclarations ne sont pas requises, mais elles vous permettent de manipuler les objets de la BDD sans faire appel à leur nom complet, long et lourd à manipuler.
Par convention, ces déclarations se font au début du code, avant les déclarations d'espaces de noms ou de classes.
Imports
System.Data
Imports
Oracle.DataAccess.Client
' ODP.NET Oracle managed provider
using
System.
Data;
using
Oracle.
DataAccess.
Client;
// ODP.NET Oracle managed provider
IV. Chaînes de connexion et objets▲
Une chaîne de connexion Oracle est intimement liée à la méthode de résolution des noms. Imaginons que nous ayons un alias de BDD OraDB déclaré comme suit dans le fichier tnsnames.ora :
OraDb=
(
DESCRIPTION=
(
ADDRESS_LIST=
(
ADDRESS=(
PROTOCOL=
TCP)(
HOST
=
OTNSRVR)(
PORT
=
1521
))
)
(
CONNECT_DATA=
(
SERVER
=
DEDICATED)
(
SERVICE_NAME=
ORCL)
)
)
Pour utiliser l'alias OraDB défini dans ce fichier, ci-dessus, vous pourriez utiliser la syntaxe suivante :
Dim
oradb As
String
=
"Data Source=OraDb;User Id=scott;Password=tiger;"
string
oradb =
"Data Source=OraDb;User Id=scott;Password=tiger;"
;
Vous pouvez vous passer du fichier tnsnames.ora en utilisant la chaîne de connexion qui suit. Il vous suffit de remplacer le nom de l'alias par ce qui le définit dans ce fichier :
Dim
oradb As
String
=
"Data Source=(DESCRIPTION="
_
+
"(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=OTNSRVR)(PORT=1521)))"
_
+
"(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL)));"
_
+
"User Id=scott;Password=tiger;"
string
oradb =
"Data Source=(DESCRIPTION="
+
"(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=OTNSRVR)(PORT=1521)))"
+
"(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL)));"
+
"User Id=scott;Password=tiger;"
;
Comme vous pouvez le constater, le login et le mot de passe sont inclus en clair dans la chaîne de connexion. C'est bien entendu l'approche la plus basique pour définir une chaîne de connexion, et elle est bien entendu déconseillée pour des raisons de sécurité.
En fait, vous devez savoir que le code compilé d'une application .NET est à peine plus sécurisé que le code source d'origine, car il est très simple de décompiler des dll et des exe .NET et donc de retrouver le code source d'origine. Il suffit de procéder à l'encryptage ou l'obfuscation du code pour parer à cette menace, mais le but de cet article n'étant pas de traiter ce sujet, nous ne nous étendrons donc pas là-dessus.
Ensuite, vous devez instancier un objet de type Connection à partir de la classe Connection. La chaîne de connexion doit bien entendu y être associée.
Dim
conn As
New
OracleConnection
(
oradb)
OracleConnection conn =
new
OracleConnection
(
oradb);
Comme vous l'aurez remarqué, le constructeur (i.e. la procédure de création) de l'objet Connection peut être surchargé, car il accepte comme argument la chaîne de connexion précédemment définie. Il est également possible d'utiliser la syntaxe suivante :
Dim
conn As
New
OracleConnection
(
)
conn.ConnectionString
=
oradb
OracleConnection conn =
new
OracleConnection
(
);
conn.
ConnectionString =
oradb;
Après l'association de la chaîne de connexion à l'objet connexion, il suffit d'utiliser la méthode Open pour ouvrir la connexion.
conn.Open
(
)
conn.
Open
(
);
La gestion d'erreur sera abordée par la suite.
IV-A. L'objet Command▲
L'objet Command sert à préciser la commande SQL à exécuter, que ce soit une requête SQL ou un appel de procédure stockée. De la même manière que pour l'objet Connection, il doit être instancié à partir de sa classe et le constructeur peut être surchargé de la manière suivante :
Dim
sql As
String
=
"select dname from dept where deptno = 10"
Dim
cmd As
New
OracleCommand
(
sql, conn)
cmd.CommandType
=
CommandType.Text
string
sql =
"select dname from dept where deptno = 10"
;
OracleCommand cmd =
new
OracleCommand
(
sql,
conn);
cmd.
CommandType =
CommandType.
Text;
Selon la signature utilisée, la syntaxe peut varier. L'objet Command dispose de plusieurs méthodes pour exécuter la commande associée. À chaque type de commande SQL correspond une méthode distincte.
IV-B. Récupération d'une seule valeur▲
La récupération d'information de la BDD se fait en instanciant un objet DataReader via l'utilisation de la méthode ExecuteReader, qui renvoie un objet OracleDataReader. Les développeurs VB.NET peuvent obtenir la valeur renvoyée via le nom de colonne ou via la propriété Item d'indice 0. Il est également possible d'utiliser une procédure de type Accesseur pour lire cette valeur.
Dim
dr As
OracleDataReader =
cmd.ExecuteReader
(
)
dr.Read
(
)
Label1.Text
=
dr.Item
(
"dname"
) ' lecture de la colonne (via le nom de colonne)
Label1.Text
=
dr.Item
(
0
) ' lecture de la première colonne (via l'indice)
Label1.Text
=
dr.GetString
(
0
) ' lecture de la première colonne (via l'indice)
(NDLR Avec l'Option Strict On, les deux premières syntaxes ne fonctionnent pas, sauf si vous appliquez la méthode ToString() sur l'expression, avant l'affectation au label.)
Les développeurs C# doivent utiliser un Accesseur pour récupérer les données. Il existe des Accesseurs typés qui permettent de renvoyer des types de données natifs de .NET, et d'autres pour renvoyer les types de données natifs d'Oracle. C'est l'indice (de base 0) qui sert à spécifier la colonne qui doit être lue, en l'occurrence la première et la seule.
OracleDataReader dr =
cmd.
ExecuteReader
(
);
dr.
Read
(
);
label1.
Text =
dr.
GetString
(
0
);
// lecture de la première colonne (via l'indice)
Dans cet exemple simplifié, c'est la valeur de dname qui est renvoyée : c'est une chaîne de caractères et elle est affectée à la propriété Text du libellé Label1. Mais si l'on avait essayé de ramener la valeur de deptno, qui n'est pas une chaîne de caractères, nous aurions alors rencontré une erreur de « type incompatible ». Lors d'une affectation d'une valeur à une variable, si les types de données ne correspondent pas, l'application .Net tentera une conversion implicite. En cas d'incompatibilité, cette conversion implicite échouera, déclenchant alors une exception. Mais même quand cela fonctionne, il est tout de même plus rigoureux d'utiliser des conversions explicites.
Voici un exemple de conversion explicite :
Label1.Text
=
CStr
(
dr.Item
(
"deptno"
))
C# n'est pas aussi permissif que VB.NET sur les conversions implicites. Vous vous en apercevrez vous-même par la pratique :
string
deptno =
dr.
GetInt16
(
"deptno"
).
ToString
(
);
Vous pouvez de la même manière convertir une valeur simple ou un tableau.
IV-C. Close et Dispose▲
Pour se déconnecter de la BDD, vous pouvez indifféremment utiliser les procédures Close ou Dispose. La procédure Dispose fait appel à la procédure Close.
conn.Close
(
)
conn.Dispose
(
)
conn.
Close
(
);
conn.
Dispose
(
);
C# offre en outre une syntaxe spéciale qui fait automatiquement appel à la méthode Dispose lorsque l'on sort de la portée de la déclaration de la connexion. Ceci se fait en passant par le mot-clé using :
using
(
OracleConnection conn =
new
OracleConnection
(
oradb))
{
conn.
Open
(
);
OracleCommand cmd =
new
OracleCommand
(
);
cmd.
Connection =
conn;
cmd.
CommandText =
"select dname from dept where deptno = 10"
;
cmd.
CommandType =
CommandType.
Text;
OracleDataReader dr =
cmd.
ExecuteReader
(
);
dr.
Read
(
);
label1.
Text =
dr.
GetString
(
0
);
}
Vous pouvez maintenant vérifier que vous avez bien assimilé les concepts exposés précédemment dans le Lab 1 (lire des données dans la BDD) et dans le Lab 2 (ajoutons-y un peu d'interaction).
V. La Gestion d'erreurs▲
La structure « Try-Catch-Finally » de la gestion d'erreurs fait intrinsèquement partie des langages .Net. Voici un exemple simpliste de mise en œuvre de cette syntaxe :
Dim
conn As
New
OracleConnection
(
oradb)
Try
conn.Open
(
)
Dim
cmd As
New
OracleCommand
cmd.Connection
=
conn
cmd.CommandText
=
"select dname from dept where deptno = "
+
TextBox1.Text
cmd.CommandType
=
CommandType.Text
If
dr.Read
(
) Then
Label1.Text
=
dr.Item
(
"dname"
) ' ou dr.Item(0)
End
If
Catch
ex As
Exception ' intercepte toutes les erreurs
MessageBox.Show
(
ex.Message.ToString
(
))
Finally
conn.Dispose
(
)
End
Try
OracleConnection conn =
new
OracleConnection
(
oradb);
try
{
conn.
Open
(
);
OracleCommand cmd =
new
OracleCommand
(
);
cmd.
Connection =
conn;
cmd.
CommandText =
"select dname from dept where deptno = "
+
textBox1.
Text;
cmd.
CommandType =
CommandType.
Text;
if
(
dr.
Read
(
))
{
label1.
Text =
dr.
GetString
(
0
);
}
}
catch
(
Exception ex) // intercepte toutes les erreurs
{
MessageBox.
Show
(
ex.
Message.
ToString
(
));
}
finally
{
conn.
Dispose
(
);
}
Bien que ce code intercepte systématiquement toute erreur lors de la tentative de lecture des données, le résultat n'est pas très ergonomique. Voici par exemple le message que l'on obtiendrait en cas d'indisponibilité de la base :
Ce message est destiné aux DBA et développeurs d'applications, mais sera incompréhensible pour un utilisateur final. La solution passée par une gestion plus fine de la section Catch, en interceptant les messages les plus fréquemment rencontrés afin de les transformer en « langage courant ».
Catch
ex As
OracleException ' intercepte seulement les erreurs Oracle
Select
Case
ex.Number
Case
1
MessageBox.Show
(
"Insertion ou MAJ impossibles, car la clé primaire dupliquée."
)
Case
12545
MessageBox.Show
(
"La base de données n'est pas disponible."
)
Case
Else
MessageBox.Show
(
"Erreur de base de données : "
+
ex.Message.ToString
(
))
End
Select
Catch
ex As
Exception ' intercepte toutes les erreurs
MessageBox.Show
(
ex.Message.ToString
(
))
catch
(
OracleException ex) // intercepte seulement les erreurs Oracle
{
switch
(
ex.
Number)
{
case
1
:
MessageBox.
Show
(
"Insertion ou MAJ impossible, car la clé primaire est dupliquée."
);
break
;
case
12545
:
MessageBox.
Show
(
"La base de données n'est pas disponible."
);
break
;
default
:
MessageBox.
Show
(
"Erreur de base de données: "
+
ex.
Message.
ToString
(
));
break
;
}
}
catch
(
Exception ex) // intercepte toutes les erreurs
{
MessageBox.
Show
(
ex.
Message.
ToString
(
));
}
Vous aurez sans doute remarqué les exemples de code ci-dessus contiennent deux sections Catch : la première traite des erreurs propres à Oracle, et la seconde de tous les autres types d'erreurs. Les sections Catch doivent effectivement se gérer ainsi, de la plus spécifique à la plus générale. Après avoir implémenté notre gestion d'erreur proprement, notre erreur ORA-12545 provoquera maintenant le message suivant :
Le code contenu dans la section Finally est toujours exécuté, qu'une erreur ait été interceptée ou pas. En y insérant l'appel de la procédure Close ou Dispose de notre objet Connection, nous sommes sûrs que la connexion à la BDD sera toujours fermée lors de l'exécution du code de la section Try-Catch-Finally.
Tenter de fermer une connexion non ouverte ne provoquera pas d'erreur. Heureusement, puisque dans le cas où notre BDD est indisponible, la connexion n'aura alors pas été ouverte et le code de la section Finally tente de fermer une connexion inexistante, ce qui sera donc sans conséquence. Ce qui nous importe, c'est que l'appel de la méthode Close ou Dispose dans la section Finally nous assure que la connexion sera systématiquement fermée.
VI. Lecture de plusieurs valeurs via le DataReader▲
Nos précédents exemples nous ont permis de traiter une valeur unique. Un objet DataReader peut gérer les valeurs de plusieurs champs et de plusieurs enregistrements. Prenons comme premier exemple une requête avec plusieurs champs, sur un enregistrement unique :
SELECT
deptno, dname, loc FROM
dept WHERE
deptno =
10
;
Pour obtenir les valeurs de ces champs, il est possible de se baser soit sur la position de la colonne (index de base 0) , soit sur son nom.
Les indices sont attribués en fonction de l'ordre des champs de la requête.
Par exemple, la valeur de la colonne loc peut être obtenue par chacune des deux expressions suivantes : dr.Item(2) ou dr.Item(« loc »).
Voici un exemple de code qui concatène les colonnes dname et loc de notre requête ci-dessous :
Label1.Text
=
"Le département "
+
dr.Item
(
1
) +
" est à "
+
dr.Item
(
"loc"
)
Label1.
Text =
"Le département "
+
dr.
GetString
(
1
) +
" est à "
+
dr.
GetString
(
2
);
Considérons maintenant une requête susceptible de nous retourner plusieurs enregistrements :
SELECT
deptno, dname, loc FROM
dept;
Pour traiter ces enregistrements retournés par le DataReader, il suffit d'implémenter une boucle. En outre, il est souhaitable niveau interface d'utiliser un contrôle capable d'afficher plusieurs lignes. Avec l'objet DataReader, le flux de données ne peut qu'être parcouru « en avant » seulement (ForwardOnly) et est en lecture seule (ReadOnly), et il ne peut donc être lié à un contrôle acceptant le défilement bidirectionnel ou la mise à jour des données, par exemple un Windows Forms DataGrid Control. Un contrôle adapté à l'affichage des données d'un DataReader est la ListBox, comme illustré ci-dessous :
While
dr.Read
(
)
ListBox1.Items.Add
(
"Le département "
+
dr.Item
(
1
) +
" est à "
+
dr.Item
(
"loc"
))
End
While
while
(
dr.
Read
(
))
{
listBox1.
Items.
Add
(
"Le département "
+
dr.
GetString
(
1
) +
" est à "
+
dr.
GetString
(
2
);
}
Le Lab 3 (Récupérer plusieurs enregistrements multicolonnes grâce au DataReader) met l'accent sur ces concepts.
VII. Conclusion▲
Cet article vous a présenté une manière d'accéder à des données Oracle grâce aux langages VS.NET. Vous devez être maintenant capable de vous connecter à la base de données et d'en lire les données.
Basé in Houston , John Paul Cook (johnpaulcook@email.com) est un consultant en bases de données et .NET. Il est l'auteur de nombreux articles sur .NET, Oracle, ainsi que sur d'autres sujets, et il travaille sur les BDD relationnelles depuis 1986. Visual Studio 2005 et Oracle 10g font aujourd'hui partie de ses domaines de prédilection. Il possède les certifications DBA Oracle et Microsoft Certified Solution Developer sur Microsoft .NET.
NDLR Vous pourrez découvrir d'autres fonctionnalités plus avancées (transaction, utilisation des checkpoints, requêtes paramétrées) ) dans l'article Utilisation d'Oracle en .NET de Thomas Lebrun.
En ce qui concerne d'ADO.Net, plusieurs ressources existent sur notre site : Si vous débutez avec ADO.Net, je vous recommande la lecture de ces deux tutoriels de Christian Peyrusse :
ADO.NET : les objets Connection, Command et Datareader
ADO.NET : les objets DataAdapter et Dataset
Si vous souhaitez perfectionner vos connaissances sur ADO.NET, un cours (de J-M Rabilloud et Sébastien Curutchet) est disponible ici :
Cours très complet sur ADO.NET.
Lab 1 : Lire des données dans la BDD▲
1. Commencez par ajouter un bouton et un label dans la Windows Form. Arrangez-vous pour laisser un peu de place au-dessus de ces contrôles, afin de pouvoir en insérer d'autres dans le Lab 2.
2. Il nous faut maintenant implémenter le code pour la lecture des données puis leur affichage sur la Form. Nous insérerons ce code dans l'événement Click du bouton. La manière la plus simple le faire est de cliquer sur le bouton lui-même, car l'IDE vous créera alors automatiquement la procédure correspondante.
3. Ajoutez la déclaration Imports (VB.Net) avant la déclaration de la Public Class ou l'instruction using (C#) avant la déclaration de l'espace de noms.
Imports
System.Data
Imports
Oracle.DataAccess.Client
using
System.
Data;
using
Oracle.
DataAccess.
Client;
4. Pour VB.Net, ajoutez le code suivant sous l'événement Click du bouton (entre les déclarations Private Sub et End Sub), puis remplacez OTNSRVR par le nom de votre serveur :
Dim
oradb As
String
=
"Data Source=(DESCRIPTION=(ADDRESS_LIST="
_
+
"(ADDRESS=(PROTOCOL=TCP)(HOST=OTNSRVR)(PORT=1521)))"
_
+
"(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL)));"
_
+
"User Id=scott;Password=tiger;"
Dim
conn As
New
OracleConnection
(
oradb)
conn.Open
(
)
Dim
cmd As
New
OracleCommand
cmd.Connection
=
conn
cmd.CommandText
=
"select dname from dept where deptno = 10"
cmd.CommandType
=
CommandType.Text
Dim
dr As
OracleDataReader =
cmd.ExecuteReader
(
)
dr.Read
(
)
Label1.Text
=
dr.Item
(
"dname"
) ' ou dr.Item(0)
conn.Dispose
(
)
Pour C#, ajoutez le code suivant sous l'événement Click du bouton (entre les accolades { et } ), puis remplacez OTNSRVR par le nom de votre serveur :
string
oradb =
"Data Source=(DESCRIPTION=(ADDRESS_LIST="
+
"(ADDRESS=(PROTOCOL=TCP)(HOST=OTNSRVR)(PORT=1521)))"
+
"(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL)));"
+
"User Id=scott;Password=tiger;"
;
OracleConnection conn =
new
OracleConnection
(
oradb);
conn.
Open
(
);
OracleCommand cmd =
new
OracleCommand
(
);
cmd.
Connection =
conn;
cmd.
CommandText =
"select dname from dept where deptno = 10"
;
cmd.
CommandType =
CommandType.
Text;
OracleDataReader dr =
cmd.
ExecuteReader
(
);
dr.
Read
(
);
label1.
Text =
dr.
GetString
(
0
);
conn.
Dispose
(
);
5. Exécutez l'application, cliquez sur le bouton, et vous devriez obtenir l'écran suivant :
Lab 2 : Ajoutons-y un peu d'interaction▲
Maintenant que les bases de l'accès aux données sont présentes dans notre code, l'étape suivante consiste à ajouter un peu d'interaction à notre application. Plutôt que d'exécuter notre requête en dur, ajoutons un contrôle TextBox qui servira à saisir le numéro de département (deptno).
1. Ajoutez un TextBox et un autre Label, comme indiqué sur l'image ci-dessous. Modifiez la propriété Text du nouveau Label à « Entrez le n° de département », et ajoutez un contrôle de saisie pour prévenir une absence de saisie :
2. Modifions la chaîne contenant la requête à exécuter :
cmd.CommandText
=
"select dname from dept where deptno = "
+
TextBox1.Text
cmd.
CommandText =
"select dname from dept where deptno = "
+
textBox1.
Text;
3. Exécutez l'application. Testez d'abord en entrant un numéro qui existe, 10 par exemple. Puis essayez ensuite avec un numéro qui n'existe pas dans la table, comme 50 : une erreur va alors se produire :
4. Implémentez la gestion d'erreur en conséquence afin de gérer la saisie de numéros inexistants dans la table. Souvenez-vous que la méthode Executereader retourne en fait un objet :
If
dr.Read
(
) Then
Label1.Text
=
dr.Item
(
"dname"
)
Else
Label1.Text
=
"Départment inexistant"
End
If
if
(
dr.
Read
(
))
{
label1.
Text =
dr.
GetString
(
0
);
}
Else
{
label1.
Text =
"Départment inexistant"
;
}
5. Retestez l'application avec les numéros que vous souhaitez, ça fonctionne. Maintenant, entrez la lettre « A » à la place d'un nombre : nouvelle erreur… Notre application a vraiment besoin d'une gestion d'erreurs un peu plus robuste.
Il est bien entendu toujours possible de contrôler les données saisies afin d'éviter ce genre d'erreurs. Néanmoins, il est préférable pour l'application d'avoir une gestion d'erreurs à toute épreuve. Il est impossible de prévoir toutes les erreurs, une gestion d'erreurs efficace est donc incontournable !
Lab 3 : Récupérer plusieurs enregistrements multicolonnes grâce au DataReader▲
Maintenant que nous avons vu comment récupérer une seule valeur, nous allons nous intéresser à la manière de récupérer plusieurs lignes contenant elles-mêmes plusieurs champs, ce grâce au DataReader. Un contrôle ListBox est à ajouter à votre feuille pour l'affichage du résultat.
1. Ajoutez le ListBox sur la feuille, et dimensionnez-le afin qu'il soit presque aussi large que la feuille, comme sur la figure 13 :
2. Dans la requête, supprimez la clause WHERE et ajoutons quelques colonnes :
cmd.CommandText
=
"select deptno, dname, loc from dept"
cmd.
CommandText =
"select deptno, dname, loc from dept"
;
3. Il nous suffit alors d'implémenter une boucle :
Pour VB.NET, modifiez votre code de cette manière :
Dim
oradb As
String
=
"Data Source=(DESCRIPTION=(ADDRESS_LIST="
_
+
"(ADDRESS=(PROTOCOL=TCP)(HOST=OTNSRVR)(PORT=1521)))"
_
+
"(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL)));"
_
+
"User Id=scott;Password=tiger;"
Dim
conn As
New
OracleConnection
(
oradb)
conn.Open
(
)
Dim
cmd As
New
OracleCommand
cmd.Connection
=
conn
cmd.CommandText
=
"select deptno, dname, loc from dept"
cmd.CommandType
=
CommandType.Text
Dim
dr As
OracleDataReader =
cmd.ExecuteReader
(
)
While
dr.Read
(
)
ListBox1.Items.Add
(
"Le département "
+
dr.Item
(
1
) +
_
" est à "
+
dr.Item
(
"loc"
))
End
While
conn.Dispose
(
)
Pour C#, procédez ainsi :
string
oradb =
"Data Source=(DESCRIPTION=(ADDRESS_LIST="
+
"(ADDRESS=(PROTOCOL=TCP)(HOST=OTNSRVR)(PORT=1521)))"
+
"(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL)));"
+
"User Id=scott;Password=tiger;"
;
OracleConnection conn =
new
OracleConnection
(
oradb);
conn.
Open
(
);
OracleCommand cmd =
new
OracleCommand
(
);
cmd.
Connection =
conn;
cmd.
CommandText =
"select deptno, dname, loc from dept"
;
cmd.
CommandType =
CommandType.
Text;
OracleDataReader dr =
cmd.
ExecuteReader
(
);
while
(
dr.
Read
(
))
{
ListBox1.
Items.
Add
(
"Le département "
+
dr.
GetString
(
1
) +
" est à "
+
dr.
GetString
(
2
));
}
conn.
Dispose
(
);
Il ne manque plus que la gestion d'erreurs, que vous pourrez retrouver dans les sources à télécharger :
http://www.oracle.com/technology/pub/files/cook_src.zip
Téléchargement et liens▲
Ce tutoriel est une traduction provenant d'un article du site Oracle Technology Network.
Vous pouvez consulter l'article original ici.
Le tutoriel au format PDF (30 pages, 711 Ko) : DOT_NET_ODT.pdf (FTP) ou DOT_NET_ODT.pdf (HTTP)