|
Site |
Cours VB.net |
|
|
|
Travailler avec un DataReader. |
|
|
Comment lire rapidement des enregistrements? Avec un DataReader.
Comment compter les enregistrements? Avec ExecuteScalar
Etudions en détail les objets Connexion, Command, DataReader.
Et s'il y a une erreur ?
Généralités:
Un objet DataReader fournit des données en lecture seule en un temps record. La seule possibilité est de se déplacer en avant.
En contrepartie de sa rapidité il monopolise la connexion.
Il faut créer un objet Connexion puis un objet Command, ensuite on exécute la propriété ExecuteReader pour créer l'objet DataReader; enfin on parcourt les enregistrements avec la méthode Read.
Exemple de DataReader avec une base access.
Il existe une base Access nommée 'consultation.mdb', elle contient une table 'QUESTIONS', dans cette table existe un champ 'NOM', je veux récupérer tous les noms et les afficher rapidement dans une ListBox.
Il faut importer les NameSpaces nécessaires.
Imports
System.DataImports
System.Data.OleDb
Il faut créer un objet connexion:
Dim MyConnexion As OleDbConnection = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data source=" & _
"C:\consultation.mdb")
Il faut donner les paramètres Provider= et Data source=
Dans le cas d'une base Access le provider (le moteur à utiliser est le moteur OLEDB Jet 4.
Il faut créer un objet Command:
Dim Mycommand As OleDbCommand = MyConnexion.CreateCommand()
Il faut donner dans la propriété CommandText la requête SQL permettant d'extraire ce que l'on désire.
Mycommand.CommandText = "SELECT NOM FROM QUESTIONS"
Ici dans la table QUESTIONS, on extrait le champ NOM
Il faut ouvrir la connexion:
MyConnexion.Open()
Il faut créer un objet DataReader:
Dim myReader As OleDbDataReader = Mycommand.ExecuteReader()
On crée une boucle permettant de lire les enregistrements les uns après les autres, on récupère le champ (0) qui est une String, on la met dans la ListBox
Do While myReader.Read()
ListBox1.Items.Add(myReader.GetString(0))
Loop
Remarquons que le champ récupéré est récupéré typé (ici une string grâce à GeString); il y a d'autres types: GetDateTime, GetDouble, GetGuid, GetInt32, GetBoolean, GetChar, GetFloat, GetByte, GetDecimal etc..; il est possible de récupérer sans typage: on aurait écrit myReader(0) ou utiliser GetValue (on récupère un objet).
Read avance la lecture des données à l'enregistrement suivant , il retourne True s'il y a encore des enregistrements et False quand il est en fin de fichier; cela est utilisé pour sortir de la boucle Do Loop.
On ferme pour ne pas monopoliser.
myReader.Close()
MyConnexion.Close()
On aurait pu libérer la connexion automatiquement dès la lecture terminée en ajoutant un argument:
Dim myReader As OleDbDataReader = Mycommand.ExecuteReader(CommandBehavior.CloseConnection)
Simple, non!! (Je rigole!!)
Cela donne:
Imports
SystemImports
System.DataImports
System.Data.OleDbImports
Microsoft.VisualBasicPublic
Class Form1 Inherits System.Windows.Forms.FormPrivate Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim MyConnexion As OleDbConnection = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data source=" & _
"C:\consultation.mdb")
Dim Mycommand As OleDbCommand = MyConnexion.CreateCommand()
Mycommand.CommandText = "SELECT NOM FROM QUESTIONS"
MyConnexion.Open()
Dim myReader As OleDbDataReader = Mycommand.ExecuteReader()
Do While myReader.Read()
ListBox1.Items.Add(myReader.GetString(0))
Loop
myReader.Close()
MyConnexion.Close()
End SubEnd
Class
Dans le cas d'une base SQLSERVEUR, on aurait les changements suivant:
Imports System.Data.SqlClient
Dim
MyConnexion As SqlConnection = New SqlConnection("Data Source=localhost;" & _
"Integrated Security=SSPI;Initial Catalog=northwind")
Dim
Mycommand
As
SqlCommand = MyConnexion.CreateCommand()
Comment compter?
Avec ExecuteScalar de l'objet Command on peut récupérer les résultats d'une requête Sql qui contient une instruction COUNT (comptage) AVG (moyenne) MIN (valeur minimum) MAX (valeur maximum) SUM (somme)
Exemple: compter le nombre de questions:
Mycommand.CommandText = "SELECT COUNT(*) FROM QUESTIONS"
MyConnexion.Open()
Dim iResultat As Integer = Mycommand.ExecuteScalar()
Voyons en détails les objets utilisés:
L'objet Connection:
Il permet de définir une connexion.
Il faut donner les paramètres 'Provider='indiquant le moteur de BD et 'Data source=' indiquant le chemin et le nom de la BD. Il peut être nécessaire de donner aussi 'Password=' le mot de passe , 'User ID=' Admin pour l'administrateur par exemple.
Il faut mettre ces paramètres avec le constructeur, ou dans la propriété ConnectionString.
Dans le cas d'une base Access le provider (le moteur à utiliser) est le moteur OLEDB Jet 4.
Il y a d'autres propriétés:
State état de la connexion (Open, Close, Connecting, Executing, Fetching, Broken)
Open, Close
ConnectionTimeOut,
BeginTransaction,
..
L'objet Command:
Pour chaque provider il y a un objet Command spécifique:
SqlCommand, OleDbCommand, mais tous les objets 'Command' on la même interface, les mêmes membres.
CommandType indique comment doit être traité la commande CommandText:
Text ; par défaut (exécution direct des instructions SQL contenues dans CommandText)
StoredProcedure: exécution de procédure stockée dont le nom est dans CommandText.
Tabledirect?
Command permet de définir la commande à exécuter: SELECT UPDATE, INSERT, DELETE. en utilisant le membre CommandText
(Seul SELECT retourne des données)
CommandTimeOut indique la durée en secondes avant qu'une requête qui plante soit abandonnée.
ExecuteReader exécute le code SQL de CommandText et retourne un DataReader.
ExecuteScalar fait de même mais retourne les champs de la premier colonne pour une fonction Count ou Sum.
ExecuteNoQuery exécute le code SQL de CommandText (généralement une mise à jour par UPDATE, INSERT, DELETE ou un ajout de table) sans retourner de données.
L'objet DataReader
Pour chaque provider il y a un objet 'DataReader' spécifique:
SqlDatReader, OleDbDataReader
On a vu le membre Read qui avance la lecture des données à l'enregistrement suivant , il retourne True s'il y a encore des enregistrements et False quand il est en fin de fichier.
On a vu GetDateTime, GetDouble, GetGuid, GetInt32, GetBoolean, GetChar, GetFloat, GetByte, GetDecimal permettant de récupérer les valeurs typées des champs.
Il a bien d'autres propriétés:
GetName retourne le nom du champ (numéro du champ en paramètre)
GetOrdinal fait l'inverse: retourne le numéro du champ (nom en paramètre)
FieldCount retourne le nombre de colonne.
GetDataTypeName retourne le nom du type de donnés.
IsDBNull retourne True si le champ est vide
......
Exceptions:
Chaque SGDB a des erreurs spécifiques. Pour les détecter il faut utiliser les types d'erreur spécifiques: SqlException et OleDbException par exemple:
Exemple d'interception d'erreur:
Try
MyConnection.Open()
Catch ex As OleDbException
MsgBox(ex.Message)
End Try
|
|
|
|
|