Cours Base de Données er ADO.Net
...
2 Les bases de données
2.1 Les fournisseurs de données
Chaque fournisseur de données permet la communication avec un type de base de données au travers d’une API. Une API (Application Programming Interface) est l’interface qui permet l’accès de logiciel par un autre. Ces fournisseurs permettent de récupérer et de transférer des modifications entre l’application et une base de données. Toutes les classes permettant d’utiliser ces fournisseurs se trouvent dans l’espace de nom System.Data. Sur le Framework 3.5, il existe quatre types de fournisseurs :
Ø Sql Server
Ø OLE DB
Ø OBDC
Ø Oracle
Chaque fournisseur est relié à une base de données propre, c'est-à-dire qu’il est compatible à l’API de sa base de données. Cependant, les bases de données peuvent implémenter plusieurs API (par exemple en installant certains pilotes comme ODBC pour l’ODBC) :
SQL Server Les classes de ce fournisseur se trouvent dans l’espace de nom
System.Data.SqlClient, chaque nom de ces classes est préfixé par
Sql. SQL Server à accès au serveur sans utiliser d’autres couches logicielles le rendant plus performant.
OLE DB Les classes de ce fournisseur se trouvent dans l’espace de nom System.Data.OleDb, chaque nom de ces classes est préfixé par OleDb. Ce fournisseur exige l’installation de MDAC (Microsoft Data Access Components). L’avantage de ce fournisseur est qu’il peut dialoguer avec n’importe quelle base de données le temps que le pilote OLE DB est installé dessus, mais par rapport à SQL server, OLE DB utilise une couche logicielle nommée OLE DB ; il requiert donc plus de ressources diminuant par conséquent les performances.
ODBC Les classes de ce fournisseur se trouvent dans l’espace de nom
System.Data.Odbc, chaque nom de ces classes est préfixé par
Odbc. Tout comme l’OLE DB, ODBC exige l’installation de MDAC.
Il fonctionne avec le même principe qu’OLE DB mais au lieu d’utiliser une couche logicielle, il utilise le pilote ODBC.
Oracle Les classes de ce fournisseur se trouvent dans l’espace de nom
System.Data.OracleClient, chaque nom de ces classes est préfixé par Oracle. Il permet simplement de se connecter à une source de données Oracle.
Afin que l’accès aux données soit sûr, les fournisseurs de données doivent être disponibles sur le poste de travail. La méthode GetFactoryClasses de la classe DbProviderFactories permet de donner les fournisseurs disponibles sur le poste de travail en question. Il faut, par contre, ajouter l’espace de nom System.Data.Common. Par exemple :
‘VB
Imports System.Data;
Imports System.Data.Common; //A rajouter
Sub Main()
Dim listeFournisseur As DataTable
listeFournisseur = DbProviderFactories.GetFactoryClasses()
For Each colonne As DataColumn In listeFournisseur.Columns
Console.Write(colonne.ColumnName + vbTab)
' Affiche le nom des colonnes
Next
Console.WriteLine(vbNewLine + vbNewLine)
For Each ligne As DataRow In listeFournisseur.Rows
' Affiche chaque ligne
For Each colonne As DataColumn In listeFournisseur.Columns
' Affiche les cellules
Console.Write(ligne.Item(colonne.ColumnName) + vbTab)
Next
Console.WriteLine(vbNewLine + vbNewLine) ' Retour à la ligne
Next
End Sub
2.2 Accéder à la base de données
Pour dialoguer avec la base de données, tous ces fournisseurs implémentent six classes de bases :
Classe
Description
Command Stocke les informations sur la commande et permet son exécution sur le serveur de base de données.
CommandBuilder Permet de générer automatiquement des commandes ainsi que des paramètres pour un DataAdapter.
Connection Permet d’établir une connexion à une source de données spécifiée.
DataAdapter Permet le transfert de données de la base de données vers l'application et inversement (par exemple pour une mise à jour, suppression ou modification de données). Il est utilisé en mode déconnecté (voir partie 5.4).
DataReader Permet un accès en lecture seule à une source de données.
Transaction Représente une transaction dans le serveur de la base de données.
Remarque : La classe Connection n’apparaît pas dans le Framework 3.5. En effet, les classes des fournisseurs managés ont leur propre classe tel que SqlConnection.
2.3 Interface portable
Les classes de chaque fournisseur varient, et donc par conséquence, le code devient spécifique à un fournisseur. Mais il existe une solution pour remédier à ce problème : on peut utiliser comme type de données les interfaces qu’elles implémentent. En effet, les classes spécifiques aux fournisseurs permettront juste d’établir la connexion, on pourra ensuite utiliser que ces interfaces. Les six classes données dans le tableau précédent implémentent leurs interfaces respectives :
Interface Description
IDataAdapter Permet de remplir et actualiser un objet
DataSet et de mettre à jour une source de données.
IDataReader Permet de lire un ou plusieurs flux de données en lecture seule à la suite de l’exécution d’une commande.
IDataParameter Permet d’implémenter un paramètre pour une commande.
IDbCommand Permet de donner une commande qui s’exécutera au moment de la connexion à une source de données.
IDbConnection Représente une connexion unique avec une source de données.
IDbDataAdapter Représente un jeu de méthodes qui permet d’exécuter des opérations sur des bases de données relationnelles (insertion, sélection, ...).
IDbTransaction Représente une transaction à exécuter au niveau d’une source de données.
Ces interfaces ne montrent pas l’étendue des possibilités que peut donner un fournisseur managé. En effet, les fournisseurs managés comprennent leurs propres classes permettant plus d’actions ou en les améliorant.
Voici un exemple de code utilisant ces interfaces :
‘VB
Imports System.Data;
Imports System.Data.Common; Imports System.Data.SqlClient; //A rajouter
Sub Main()
Dim requete, connexionString As String connexionString = "Data Source=.\SQLServeur;Initial Catalog=DotNetFrance;Integrated Security=true;" requete = "SELECT * FROM Employe"
Dim connexion As IDbConnection = New SqlConnection(connexionString)
Dim commande As IDbCommand = connexion.CreateCommand()
commande.CommandText = requete
commande.CommandType = CommandType.Text
connexion.Open()
Dim lire As IDataReader = commande.ExecuteReader()
While (lire.Read())
Console.WriteLine("ID : {0} | Nom : {1} | Prenom : {2} |
RoleNumero : {3}", lire.GetInt32(O), lire.GetString(1), lire("Prenom"),
lire("Role"))
End While
connexion.Close()
connexion.Dispose()
Console.ReadLine() End Sub
2.4 Mode connecté / Mode déconnecté
L’ADO.NET permet de séparer les actions d’accès ou de modification d’une base de données. En effet, il est possible de manipuler une base de données sans être connecté à celle-ci, il suffit juste de se connecter pendant un court laps de temps afin de faire une mise à jour. Ceci est possible grâce au DataSet. C’est pourquoi, il existe deux types de fonctionnements :
Ci-après, la différence par avantages et inconvénients :
…
Il n’existe pas un mode meilleur que l’autre, tout dépend de l’utilisation que l’on compte en faire.
3 Etablir une connexion
3.1 Les chaînes de connexions
Dans un mode connecté, il faut tout d’abord connecter l’application à la base de données. Nous utiliserons SQL Server 2005 pour la suite. Pour ouvrir cette connexion il faut d’abord déclarer une variable, ici ce sera « connexion » :
‘VB
Dim connexion As SqlConnection
//C#
SqlConnection connexion
La propriété ConnectionString permet d’indiquer les paramètres de connexion. Cela se fait sous forme de chaîne de caractères, tel que par exemple :
‘VB
connexionString = "Data Source=.\SQLServeur;Initial Catalog=DotNetFrance;Integrated Security=true;"
//C#
connexionString = @"Data Source=.\SQLServeur;Initial Catalog=DotNetFrance;Integrated Security=true;";
Voici les différents paramètres disponibles dans une ConnectionString :
Paramètre Description
Connect Timeout Indique le temps d’attente de connexion en seconde. Ce laps de temps dépassé, une exception est levée.
Connection LifeTime Indique la durée de vie d’une connexion dans un pool, la valeur 0 (zéro) correspond à l’infini.
Connection Reset Indique si la connexion a été réinitialisée lors de son retour dans un pool.
Data Source Indique le nom ou l’adresse réseau du serveur.
Initial Catalog Indique le nom de la base de données où l’application doit se connecter.
Integrated Security
Indique s’il faut un nom et un mot de passe.
Si la valeur et sur False, un login et password seront demandés.
Max Pool Size Indique le nombre maximum de connexion dans un pool. Par défaut, le nombre maximum de connexions est 100.
Min Pool Size Indique le nombre minimum de connexion dans un pool.
Persist Security Info Indique si le nom et le mot de passe est
visible par la connexion.
Pwd Indique le mot de passe associé au compte
SQL Server.
Pooling Indique si une connexion peut être sortie d’un pool.
User ID Indique le nom du compte SQL Server.
Afin de vérifier l’état d’une connexion, ADO.NET propose l’énumération ConnectionState. Il possède différentes propriétés :
Propriété Description
Broken Permet de savoir si la connexion est interrompue, cette connexion peux se fermer puis se rouvrir.
Closed Permet de savoir si l’objet connexion est fermé.
Connecting Permet de savoir si l’objet connexion est en cours de connexion.
Executing Permet de savoir si une commande est en train de s’exécuter.
Fetching Permet de savoir si l’objet connexion est en train de récupérer des données.
Open Permet de savoir si l’objet connexion est ouvert.
Voici, par exemple :
3.2 Les pools de connexions
Afin de réduire le coût en ressource engendré par les connexions à des bases de données, l’ADO.NET propose une technique d’optimisation : le pool de connexion. Lorsque qu’une application ouvre une nouvelle connexion, un pool est créé. Les pools permettent de stocker toutes les requêtes récurrentes. Chaque fois qu’un utilisateur ouvre une connexion avec la même ConnectionString qu’un pool, le dispositif de connexion vérifie s’il y a une place disponible dans ce pool, si le MaxPoolSize n’est pas atteint, la connexion rentre dans l’ensemble. Un pool est effacé lorsqu’une erreur critique est levée.
Les pools sont paramétrables dans le ConnectionString et une connexion est retirée d’un pool lorsqu’elle est inactive depuis une certaine durée.
...
4 Mode connecté 4.1 Les commandes
Contrairement à une base de données, les requêtes SQL et les procédures stockées sont exécutées à partir de commandes. Les commandes contiennent toutes les informations nécessaires à leur exécution et effectuent des opérations telles que créer, modifier ou encore supprimer des données d’une base de données. Vous utilisez ainsi des commandes pour faire des exécutions de requêtes SQL qui renvoient les données nécessaires.
Remarque : les requêtes SQL et les procédures stockées sont deux choses différentes. En effet les procédures stockées sont des requêtes SQL déjà enregistrées dans la mémoire cache du serveur.
Chaque fournisseur de base de données possède leurs propres objets Command qui sont les suivantes :
Nom
Type de sources de données
SqlCommand SQL Server
OleDbCommand OLE DB
OdbcCommand ODBC
OracleCommand Oracle
Il existe plusieurs propriétés et méthodes communes à chaque fournisseur pour gérer des commandes, voici les principales :
Propriétés
CommandText Permet de définir l’instruction de requêtes
SQL ou de procédures stockées à exécuter.
Lié à la propriété CommandType.
CommandTimeout Permet d’indiquer le temps en secondes avant de mettre fin à l’exécution de la commande.
CommandType Permet d’indiquer ou de spécifier la manière dont la propriété CommandText doit être exécutée.
Connection Permet d’établit une connexion.
Parameters
C’est la collection des paramètres de commandes. Lors de l’exécution de requêtes paramétrées ou de procédures stockées, vous devez ajouter les paramètres objet dans la collection.
Transaction Permet de définir la SqlTransaction dans laquelle la SqlCommand s’exécute.
Méthodes
Cancel Permet de tenter l’annulation de l’exécution d’une commande.
ExecuteNonQuery
Permet d’exécuter des requêtes ou des procédures stockées qui ne retournent pas de valeurs.
ExecuteReader Permet d’exécuter des commandes et les retourne sous forme de tableau de données (ou des lignes).
ExecuteScalar Permet d‘exécuter les requêtes ou les procédures stockées en retournant une valeur unique.
ExecuteXMLReader
Permet de retourner les données sous le format XML.
Vous pouvez aussi manipuler des événements. Voici les deux principaux :
Disposed
Permet d’appeler la dernière méthode avant que l’objet ne soit détruit.
StatementCompleted (seulement pour
SqlCommand)
Se produit lorsque l’exécution d’une instruction se termine.
4.2 Utiliser des commandes
Une fois la connexion établie, la classe SqlCommand permet d’appeler la méthode CreateCommand qui permettra l’exécution de commandes SQL.
Il existe trois méthodes afin de créer une commande :
Ø Vous pouvez directement utiliser un des constructeurs de la classe SqlCommand. Par contre cela nécessite l’utilisation de deux propriétés : CommandText et Connection. Voici un exemple utilisant cette méthode :
‘VB
Dim commande As SqlCommand = New SqlCommand() commande.Connection = connexion
commande.CommandText = "SELECT * FROM Employe"
//C#
SqlCommand commande= new SqlCommand(); commande.Connection = connexion;
commande.CommandText = "SELECT * FROM Employe";
Ø La deuxième méthode est l’utilisation d’un constructeur surchargé, voici par exemple :
‘VB
commande = New SqlCommand("SELECT * FROM Employe", connexion)
//C#
commande = new SqlCommand("SELECT * FROM Employe", connexion);
Ø La dernière méthode est d’utiliser la méthode CreateCommand de l'objet de connexion comme dans l’exemple ci-dessous :
‘VB
Dim commande As SqlCommand = connexion.CreateCommand() commande.CommandText = "SELECT * FROM Employe"
//C#
SqlCommand commande = connexion.CreateCommand(); commande.CommandText = "SELECT * FROM Employe";
Le fonctionnement pour exécuter une procédure stockée est quasiment identique à l’exécution d’une requête SQL classique. Il faut que la propriété CommandText contienne le nom de la procédure, par contre la propriété CommandType doit prendre la valeur StoredProcedure au lieu de Text. L’avantage d’une procédure stockée est une amélioration de la performance car la procédure se trouve précompilée dans le cache du serveur. Voici un exemple qui permet d’afficher toutes les informations d’un utilisateur de la table Employe :
‘VB
Dim connexion As SqlConnection = New SqlConnection("Data Source=.\SQLServeur;Initial Catalog=DotNetFrance;Integrated Security=True")
Dim Command As SqlCommand = connexion.CreateCommand() connexion.Open()
Dim id As String
Dim requete As String = "RecupInformation"
Command.CommandText = requete
Command.CommandType = CommandType.StoredProcedure
Console.WriteLine("Quel est l'id de la personne sur laquelle vous voulez les informations ?")
id = Console.ReadLine()
Dim paramIdToKnow As SqlParameter = New SqlParameter("@IdToKnow", id) Command.Parameters.Add(paramIdToKnow)
Dim lecture As IDataReader = Command.ExecuteReader()
While (lecture.Read())
Console.WriteLine("Id : {0} Nom : {1} Prenom : {2} Role : {3}", lecture("ID"), lecture.GetString(1), lecture.GetString(2), lecture.GetInt32(3))
End While
connexion.Close() connexion.Dispose()
//C#
SqlConnection connexion = new SqlConnection(@"Data Source=.\SQLServeur;Initial Catalog=DotNetFrance;Integrated Security=True");
SqlCommand command = connexion.CreateCommand();
connexion.Open();
string id;
string requete = "RecupInformation";
command.CommandText = requete;
command.CommandType = CommandType.StoredProcedure;
Console.WriteLine("Quel est l'id de la personne sur laquelle vous voulez les informations ?");
id = Console.ReadLine();
SqlParameter paramIdToKnow = new SqlParameter("@IdToKnow", id); command.Parameters.Add(paramIdToKnow);
IDataReader lecture = command.ExecuteReader();
while (lecture.Read())
{
Console.WriteLine("Id : {0} Nom : {1} Prenom : {2} Role : {3}", lecture["ID"], lecture.GetString(1), lecture.GetString(2), lecture.GetInt32(3));
}
connexion.Close(); connexion.Dispose();
Afin d’exécuter une instruction SQL qui renvoie plusieurs valeurs, on peut utiliser la méthode ExecuteReader; elle va retourner l’objet Datareader qui va permettre la lecture des données. Si l’instruction SQL ne doit renvoyer qu’une valeur unique, on peut utiliser la méthode ExecuteScalar qui va à la fois s’occuper de l’exécution et retourner la valeur.
Voici, par exemple, un code permettant d’afficher la base de données Dot-Net France :
‘VB
Dim connexion As SqlConnection = New SqlConnection("Data Source=.\SQLServeur;Initial Catalog=DotNetFrance;Integrated Security=True")
Dim Command As SqlCommand = connexion.CreateCommand()
Dim requete As String = "SELECT e.ID 'ID', e.Nom, e.Prenom, r.Nom FROM Employe e, Role r WHERE(e.Role = r.ID) "
Command.CommandText = requete
connexion.Open()
Dim lire As SqlDataReader = Command.ExecuteReader()
Console.WriteLine("Lecture du DataReader" + vbNewLine + vbNewLine) ' Lit les informations de la base de données
While (lire.Read())
Console.WriteLine("Id : {0} Nom : {1} Prenom : {2} Role : {3}", lire("ID"), lire.GetString(1), lire.GetString(2), lire.GetString(3)) End While
' Permet d'afficher
connexion.Close() connexion.Dispose()
//C#
SqlConnection connexion = new SqlConnection(@"Data Source=.\SQLServeur;Initial Catalog=DotNetFrance;Integrated Security=True");
SqlCommand command = connexion.CreateCommand();
string requete = "SELECT e.ID 'ID', e.Nom, e.Prenom, r.Nom FROM Employe e, Role r WHERE(e.Role = r.ID) ";
command.CommandText = requete;
connexion.Open();
SqlDataReader lire = command.ExecuteReader(); // Lit les informations de la base de données
Console.WriteLine("Lecture du DataReader \n\n");
while (lire.Read())
{
Console.WriteLine("Id : {0} Nom : {1} Prenom : {2} Role : {3}",
lire["ID"], lire.GetString(1), lire.GetString(2), lire.GetString(3));
}
// Permet d'afficher
connexion.Close(); connexion.Dispose();
Vous devriez obtenir un affichage semblable à :
Vous pouvez également exécuter des commandes qui vous renvoient les données au format XML. Pour cela vous devez régler la propriété CommandText de votre instruction SQL au format XML puis faire appel à la méthode ExecuteXMLReader qui retourne un objet XmlReader (dont la classe est stockée dans System.Xml). Lorsque vous configurez votre commande, vous pouvez utiliser le Query Designer afin de créer et de personnaliser vos requêtes. Donc vous devez sélectionner votre base de données dans le Server Explorer puis cliquer sur New Query. Vous ouvrez ainsi le Query Designer et pourrez alors non seulement créer votre requête mais en plus la personnaliser (tableau, affichage...).
Durant un échange entre une application et une base de données, l’application est bloquée durant l’attente de la réponse du serveur. Pour remédier à ce problème, l’ADO.NET propose les commandes asynchrones. En effet, ces commandes permettent à l’application de faire autre chose en attendant la réponse du serveur.
Voici les méthodes qui sont utilisées lors d’un processus asynchrone :
BeginExecuteNonQuery
Commence la version asynchrone de la méthode
ExecuteNonQuery.
BeginExecuteReader
Commence la version asynchrone de la méthode
ExecuteReader.
BeginExecuteXmlReader
Commence la version asynchrone de la méthode
ExecuteXmlReader.
EndExecuteNonQuery
Appeler cette méthode après l’événement
StatementCompleted afin d’achever l’exécution de la commande.
EndExecuteReader
Appeler cette méthode après l’événement
StatementCompleted afin de renvoyer le DataReader avec les données retournées par la commande.
EndExecuteXmlReader
Appeler cette méthode après l’événement
StatementCompleted afin de renvoyer le XmlReader avec les données retournées par la commande.
4.3 Les paramètres de commandes SQL
Un paramètre peut être considéré comme un type de variable qui permet de transmettre des valeurs et des retours entre votre demande et la base de données. Comme toute variable dans une application, les paramètres sont créés pour contenir un certain type de données. Les types de données des paramètres sont assignés en utilisant les types définis dans l’énumération de l’objet System.Data.SqlDbType. Cette énumération contient toute une liste des types disponibles dans SQL Server.
Vous définissez un paramètre à une requêtes SQL (ou à une procédure stockée) lorsque vous changez les critères de votre requêtes rapidement. Par exemple l’utilisation typique d’utilisation d’un paramètre est dans la clause WHERE de votre requête SQL. Les paramètres vous permettent aussi de contrôler la façon dont est entré un utilisateur dans une requête.
Remarque : Pour SQL Server le symbole @ est utilisé pour créer des paramètres nommés. Le symbole point d’interrogation ? (paramètre anonyme) est utilisé dans les autres types de base de données.
4.4 Les types de paramètres
La modification des informations contenue dans votre base de données est faite par les instructions SQL. Il existe quatre types de paramètres :
- le premier est de type Input, c'est-à-dire que vous voulez utiliser un paramètre pour envoyer des données à la base de données.
- le second est le type Output qui lui est utilisé lorsqu’on veut récupérer des données.
- le troisième est l’InputOutput qui est exploité pour faire les deux actions précédentes, c'est-à-dire envoyer et récupérer des données.
- enfin le dernier type est le ReturnValue qui retourne simplement une valeur assignée.
4.5 Créer un paramètre
Paramétrer vos requêtes sert aussi à les rendre génériques. Les paramètres servent à prendre un emplacement dans une requête qui sera plus tard utilisé dans votre code.
La classe SqlParameter permet de créer des objets de type Sqlparameter contenant : le nom, la valeur et la direction d’utilisation du paramètre.
Voici un exemple permettant d’ajouter un utilisateur dans la base de données DotNetFrance :
‘VB
Dim connexion As SqlConnection = New SqlConnection("Data Source=.\SQLServeur;Initial Catalog=DotNetFrance;Integrated Security=True")
Dim Command As SqlCommand = connexion.CreateCommand() Dim nom, prenom, requete, role As String
Console.WriteLine("Entrez les données suivantes :" + vbNewLine)
’ Ecrit directement dans la console
Console.WriteLine("Nom : ")
nom = Console.ReadLine()
’ Permet de lire la valeur donnée
Console.WriteLine(vbNewLine + "Prenom : ")
prenom = Console.ReadLine()
Console.WriteLine(vbNewLine + "Role (0 Stagiaire | 1 Manager) : ")
role = Console.ReadLine()
requete = "INSERT INTO Employe VALUES(@nom, '" + prenom + "'," + role +
")"
Dim param As SqlParameter = New SqlParameter("@nom", nom)
’ Permet de paramétrer "nom"
Command.Parameters.Add(param)
’ Ajoute le paramètre param à la collection Parameters
Command.CommandText = requete
connexion.Open()
Dim nbrEnregistrementAffecte As String = Command.ExecuteNonQuery().ToString()
Console.WriteLine(vbNewLine + nom + " " + prenom + " " + role + " a été ajoute.")
Console.WriteLine("Il y a " + nbrEnregistrementAffecte + " enregistrement(s) affecte par la requete")
SqlConnection connexion = new SqlConnection(@"Data
Source=.\SQLServeur;Initial Catalog=DotNetFrance;Integrated Security=True");
SqlCommand command = connexion.CreateCommand();
string nom, prenom, requete;
int role;
Console.WriteLine("Entrez les données suivantes :\n");
// Ecrit directement dans la console
Console.WriteLine("Nom : ");
nom = Console.ReadLine();
// Permet de lire la valeur donnée
Console.WriteLine("\nPrenom : ");
prenom = Console.ReadLine();
Console.WriteLine("\nRole (0 Stagiaire | 1 Manager) : ");
role = int.Parse(Console.ReadLine());
requete = "INSERT INTO Employe VALUES(@nom, '" + prenom + "'," + role +
")";
SqlParameter param = new SqlParameter("@nom", nom);
// Permet de paramétrer "nom"
command.Parameters.Add(param);
// Ajoute le paramètre param à la collection Parameters
command.CommandText = requete;
connexion.Open();
int nbrEnregistrementAffecte = command.ExecuteNonQuery(); Console.WriteLine("\n" + nom + " " + prenom + " " + role + " a ete ajoute.");
Console.WriteLine("Il y a " + nbrEnregistrementAffecte + " enregistrement(s) affecte par la requete");
Remarque : Vous pouvez aussi ajouter des paramètres à vos Command Object en saisissant la méthode GetCostCommand.
4.6 Les BLOBs
Les BLOBs dans une base de données ne sont pas de simples données de types chaines de caractères, ce sont des les types de données binaires du type graphiques, photos, documents enregistrés en format binaire ou bien des exécutables (ils peuvent contenir tous les types), par conséquence leur utilisation est plus complexe.
La taille d’un BLOB peut dépasser plusieurs Go et par conséquence peut nuire aux performances au moment d’un chargement. En revanche le .NET Framework fournit des classes permettant le déplacement de grosses quantités de données binaires. Ces classes (comme BinaryReader ou BinaryWriter) se trouvent dans l’espace de nom System.IO.
4.7 Le DataReader
Le DataReader permet un accès en lecture seule à des enregistrements, c'est-à-dire qu’il est impossible de revenir en arrière sur les enregistrements lus. Il n’a été créé que pour la lecture pure et simple de données. Le DataReader doit toujours être associé à une connexion active, c'est-à-dire qu’il ne peut pas se déconnecter, effectuer quelque chose puis se reconnecter pour une mise à jour.
Il existe plusieurs Datareader suivant le fournisseur utilisé, par exemple nous avons SqlDataReader ou encore OracleDataReader.
Le DataReader comprend plusieurs méthodes : GetBytes, GetChars ou GetString. GetString servent pour les données caractères ; GetBytes et GetChars permettent de retourner une valeur de type long, qui représente le nombre de caractères ou d’octets retournés.
4.8 Copier un grand nombre de données
Pour copier un grand nombre de données vers une table de données de façon performante (c'est-à-dire sans trop utiliser de ressources et de temps) il existe deux applications :
Ø Le Framework .NET qui propose dans le namespace System.Data.SqlClient l’objet SqlBulkCopy.
Ø SQL Server qui propose la requête BULK INSERT SQL.
Ces solutions permettent dans la majorité des cas de rendre plus performant le transfert.
4.9 Les transactions
Les transactions permettent de regrouper des commandes SQL dans une même entité. La transaction permettra que si une des commandes échoue alors l’opération sera arrêtée et la base de données retrouvera son état initial.
Pour créer une transaction, il suffit d’instancier votre Transaction puis de l’assigner en appelant la méthode BeginTransaction à la connexion. Voici un exemple de création d’une transaction :
‘VB
‘Création d’une transaction
Dim transaction As New SqlTransaction
‘Définit la transaction à votre connexion Transaction = VotreConnexion.BeginTransaction()
//C#
‘Création d’une transaction SqlTransaction transaction
‘Définit la transaction à votre connexion transaction = VotreConnexion.BeginTransaction() ;
De plus les transactions reposent sur le principe de quatre caractéristiques appelé ACID qui apporte plus de clarté sur la définition d’une transaction :
- Atomicité, qui signifie que la mise à jour de la base de données doit être totale ou nulle, c’est le principe du “tout ou rien”.
- Cohérence, qui indique que les modifications apportées doivent être valides.
- Isolation, qui définit que les transactions lancées au même moment ne doivent pas s’interférer entre elles.
- Durabilité, qui assure que toutes les transactions sont lancées de manière définitive.
Les transactions sont managées au niveau de la connexion. Par conséquent nous pourrons commencer une transaction en ouvrant une connexion avec une base de données pour ensuite commencer les transactions en appelant la méthode BeginTransaction issues d’une instance de la classe SqlTransaction. Puis vous devez définir quelle commande nécessite une transaction. Enfin à la fin du traitement des données vous avez la possibilité soit de valider vos transactions grâce à la méthode Commit soit de les annuler grâce à la méthode Rollback.
4.9.1 Niveau d’isolations des transactions
Les niveaux d’isolation vous permettent de gérer les problèmes d’intégrité des données ainsi que des accès simultanés à celles-ci par le biais des transactions. Vous trouverez ci-dessous la liste des propriétés IsolationLevel associés à l’objet Transaction :
Chaos
Les modifications en attente de transactions très isolés ne peuvent être écrasées.
ReadCommitted
Les verrouillages partagés sont maintenus pendant que les données sont en lecture pour éviter tout défaut, mais les données sont modifiables durant la transaction, entrainant une lecture non répétable ou des données “fantôme”.
ReadUncommitted
Il n’y a pas de verrouillage entrainant la possibilité de tout défaut de lecture.
RepeatableRead
Toutes les données utilisées dans une requête sont verrouillées. Par conséquence les lectures ne sont pas répétables mais des données “fantôme” peuvent exister et d’autres utilisateurs ne peuvent mettre à jour les données.
Serializable
Les verrouillages sont placés sur toutes les données qui sont utilisées dans une requête, ce qui empêche d’autres utilisateurs de mettre à jour les données.
Snapshot
Réduit le blocage par le stockage de données qu’une seul application peut lire pendant qu’une autre est train de les modifier. Cela indique que d’une seule transaction vous ne pouvez voir les modifications faites dans d’autres transactions.
Unspecified
Aucun niveau ne peut être déterminé. Ainsi si le niveau d’isolation est définit sur celui-ci alors la transaction exécute selon le niveau d’isolation par défaut du sous-jacent du type de base de données.
4.9.2 Les transactions Distribuées
En plus de créer des nouvelles transactions et de définir des niveaux d’isolation de celles-ci, vous pouvez configurez votre connexion pour l’engager dans une transaction distribuée. Une transaction distribuée est une transaction qui s’étend sur de nombreuses ressources, telles que de multiples bases de données SQL.
Exemple de mise en place d’une transaction distribuée :
‘VB
VotreConnexion.EnlistTransaction(activeTransaction)
//C#
VotreConnexion.EnlistTransaction(activeTransaction