Développer une Application .NET sur une BDD Oracle

Apprenez les mécanisme basiques mais néanmoins essentiels impliqués dans la conception d'une application .Net connectée à une base Oracle

N'hésitez pas à commenter cet article ! Commentez Donner une note à l'article (5)

Article lu   fois.

Les deux auteurs

Site personnel

Profil ProSite personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

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, pour m'avoir autorisé à traduire cet article.

Merci à Didier Danse, à David Pédehourcq, à Ronald Vasseur, et à neguib pour leurs relectures.

1. Introduction

Image non disponible


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 terme de connectivité basique, mais également en terme 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 oeuvre 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 3 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.

2. Les fournisseurs de données .NET (.Net Data Provider)

En plus d'une interface basique de connexion cliente, une application .Net requiert une 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 meilleurs 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'application 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 correcte.

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).

3. Créer un nouveau projet dans Visual Studio.NET

Démarrons Visual Studio pour créer un projet en cliquant sur le menu suivant :

Image non disponible
Figure 1: Création d'un nouveau projet dans Visual Studio.NET


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.

Image non disponible
Figure 2: La fenêtre Nouveau Projet


Vous choisirez de préférences 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é que d'un projet, il est courant de leur donner le même nom.

3.1. 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.

Image non disponible
Figure 3: Ajout d'une référence


La fenêtre Ajouter une référence apparaît :

Image non disponible
Figure 4: Selecting the ODP.NET Managed Data Provider


Dans la liste de composants proposés, sélectionnez la librairie Oracle.DataAccess.dll, cliquez sur le bouton Sélectionner, puis sur OK : le fournisseur de données est maintenant reconnu dans notre projet :

Image non disponible
Figure 5: Aperçu de l'Explorateur de solution, une fois la référence ajoutée

3.2. 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 à leurs noms complets, longs et lourds à manipuler.

Par convention, ces déclarations se font au début du code, avant les déclarations d'espaces de noms ou de classes.

VB.NET
Sélectionnez

Imports System.Data              
Imports Oracle.DataAccess.Client ' ODP.NET Oracle managed provider    
            
C#
Sélectionnez

using System.Data;              
using Oracle.DataAccess.Client; // ODP.NET Oracle managed provider
            

4. 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 :

tnsnames.ora
Sélectionnez

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 :

VB.NET
Sélectionnez

Dim oradb As String = "Data Source=OraDb;User Id=scott;Password=tiger;" 
        
C#
Sélectionnez

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 simplement de remplacer le nom de l'alias par ce qui le définit dans ce fichier :

VB.NET
Sélectionnez

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;"
        
C#
Sélectionnez

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.

VB.NET
Sélectionnez

Dim conn As New OracleConnection(oradb)
        
C#
Sélectionnez

OracleConnection conn = new OracleConnection(oradb);
        

Comme vous l'aurez remarqué, le constructeur (ie 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 :

VB.NET
Sélectionnez

Dim conn As New OracleConnection()
conn.ConnectionString = oradb
        
C#
Sélectionnez

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.

VB.NET
Sélectionnez

conn.Open() 
        
C#
Sélectionnez

conn.Open();
        

La gestion d'erreur sera abordée par la suite.

4.1. 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 :

VB.NET
Sélectionnez

Dim sql As String = "select dname from dept where deptno = 10"
Dim cmd As New OracleCommand(sql, conn)
cmd.CommandType = CommandType.Text
            
C#
Sélectionnez

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.

4.2. Récupération d'une seule valeur

La récupération d'information de la BDD se fait en 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.

VB.NET
Sélectionnez

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 2 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.

C#
Sélectionnez

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ère, 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 conversion explicites.

Voici un exemple de conversion explicite :

VB.NET
Sélectionnez

Label1.Text = CStr(dr.Item("deptno"))
            

C# n'est pas aussi permissif que VB.NET sur les conversion implicites. Vous vous en apercevrez vous-même par la pratique :

C#
Sélectionnez

string deptno = dr.GetInt16("deptno").ToString(); 
            

Vous pouvez de la même manière convertir une valeur simple ou un tableau.

4.3. 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.

VB.NET
Sélectionnez

conn.Close()
conn.Dispose()
            
C#
Sélectionnez

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 :

C#
Sélectionnez

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).

5. 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 oeuvre de cette syntaxe :

VB.NET
Sélectionnez

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
        
C#
Sélectionnez

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 :

Image non disponible
Figure 6: Une erreur ORA-12545 est remontée à l'utilisateur.


Ce message est destiné aux DBA et développeurs d'applications, mais sera incompréhensible pour un utilisateur final. La solution passé 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".

VB.NET
Sélectionnez

Catch ex As OracleException ' intercepte seulement les erreurs Oracle
    Select Case ex.Number
    Case 1
        MessageBox.Show("Insertion ou MAJ impossible 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())
        
C#
Sélectionnez

catch (OracleException ex) // intercepte seulement les erreurs Oracle
{
    switch (ex.Number)
    {
    case 1:
        MessageBox.Show("Insertion ou MAJ impossible car la clé primaire est 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 2 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 :

Image non disponible
Figure 7: L'erreur ORA-12545 est affichée dans un langage plus clair


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équences. 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.

6. 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 :

requête 1
Sélectionnez

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 2 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:

VB.NET
Sélectionnez

Label1.Text = "Le départment " + dr.Item(1) + " est à " + dr.Item("loc")         
        
C#
Sélectionnez

Label1.Text = "Le départment " + dr.GetString(1) + " est à " + dr.GetString(2);
        


Considérons maintenant une requête susceptible de nous retourner plusieurs enregistrements :

requête 2
Sélectionnez

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, comme 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 :

VB.NET
Sélectionnez

While dr.Read()
   ListBox1.Items.Add("Le départment " + dr.Item(1) + " est à " + dr.Item("loc")) 
End While
        
C#
Sélectionnez

while (dr.Read())
{
  listBox1.Items.Add("Le départment " + dr.GetString(1) + " est à " + dr.GetString(2);
}        
        

Le Lab 3 (Récupérer plusieurs enregistrements multi-colonnes grâce au DataReader) met l'accent sur ces concepts.

7. 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 certification 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 2 tutoriels de Christian Peyrusse :
ADO.NET : les objet 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 laissez un peu de place au-dessus de ces contrôles, afin de pouvoir en insérer d'autres dans le Lab 2.

Image non disponible
Figure 8: Lab 1 : votre feuille avec ses contrôles

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.

Image non disponible
Figure 9: L'événement Click attend son code ...

3. Ajouter 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.

VB.NET
Sélectionnez

Imports System.Data
Imports Oracle.DataAccess.Client
        
C#
Sélectionnez

using System.Data;
using Oracle.DataAccess.Client;
        


4. Pour VB.Net, ajouter 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 :

VB.NET
Sélectionnez

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 :

C#
Sélectionnez

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 :

Image non disponible
Figure 10: Donnée lue avec succès

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 a 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 :

Image non disponible
Figure 11: Lab 2 : votre feuille avec ses (nouveaux) contrôles.


2. Modifions la chaîne contenant la requête à exécuter :

VB.NET
Sélectionnez

cmd.CommandText = "select dname from dept where deptno = " + TextBox1.Text         
        
C#
Sélectionnez

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 :

Image non disponible
Figure 12: Une erreur non gérée


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 :

VB.NET
Sélectionnez

If dr.Read() Then
    Label1.Text = dr.Item("dname")
Else    
    Label1.Text = "Départment inexistant"
End If        
        
C#
Sélectionnez

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'erreur 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 multi-colonnes 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 :

Image non disponible
Figure 13: Ajout du ListBox sur la feuille


2. Dans la requête, supprimez la clause WHERE et ajoutons quelques colonnes :

VB.NET
Sélectionnez

cmd.CommandText = "select deptno, dname, loc from dept"        
        
C#
Sélectionnez

cmd.CommandText = "select deptno, dname, loc from dept";        
        

3. Il nous suffit alors d'implémentez une boucle :
Pour VB.NET, modifiez votre code de cette manière :

VB.NET
Sélectionnez

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épartment " + dr.Item(1) + _
                       " est à " + dr.Item("loc"))
End While

conn.Dispose()        
        

Pour C#, procédez ainsi :

C#
Sélectionnez

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épartment " + dr.GetString(1) +
                      " est à " + dr.GetString(2));
}
conn.Dispose();         
        

Il ne manque plus que la gestion d'erreur, 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)

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+