Comprendre les Recordset ADO


précédentsommairesuivant

VII. Rappels ADO

 

VII-A. L'objet Connection

Je ne vais pas me lancer ici dans une longue description de l'objet Connection. Je vais donc juste faire quelques rappels directement utilisés dans cet article.

VII-A-1. La propriété CursorLocation

Définit ou renvoie la position de la bibliothèque de curseur à utiliser. Peut prendre les valeurs adUseClient ou adUseServer. La définition de cette propriété au niveau de la connexion permet de ne pas la re déclarer au niveau d'un recordset.

VII-A-2. La propriété IsolationLevel

Cette propriété permet de définir le niveau d'isolation qu'auront les transactions faite par la connexion. Ceci permet de garantir le respect de la gestion des transactions. Elle peut prendre les valeurs :

Constante Valeur Description
adXactUnspecified -1 Le fournisseur utilise un niveau d'isolation différent de celui qui est spécifié mais ce niveau ne peut pas être déterminé.
adXactChaos 16 Valeur utilisée par défaut. Vous ne pouvez pas écraser les changements en attente des transactions dont le niveau d'isolation est supérieur.
adXactBrowse 256 À partir d'une transaction, vous pouvez voir les modifications des autres transactions non encore engagées.
adXactReadUncommitted 256 Identique à adXactBrowse
adXactCursorStability 4096 Valeur utilisée par défaut. A partir d'une transaction, vous pouvez afficher les modifications d'autres transactions uniquement lorsqu'elles ont été engagées.
adXactReadCommitted 4096 Identique à adXactCursorStability.
adXactRepeatableRead 65536 À partir d'une transaction, vous ne pouvez pas voir les modifications effectuées dans d'autres transactions, mais cette nouvelle requête peut renvoyer de nouveaux jeux d'enregistrements.
adXactIsolated 1048576 Des transactions sont conduites en isolation d'autres transactions.
adXactSerializable 1048576 Identique à adXactIsolated.

Le niveau d'isolation à utiliser dépend de votre application. La valeur la plus stricte (sure) est adXactIsolated

VII-A-3. La propriété Mode

Cette propriété permet de gérer en partie l'accès concurrentiel dans les bases de données. Comme cette propriété porte sur la connexion, elle s'applique à la source de données. Elle peut prendre les valeurs :

Constante Valeur Description
adModeUnknown 0 Valeur utilisée par défaut. Indique que les autorisations n'ont pas encore été définies ou ne peuvent pas être déterminées.
adModeRead 1 Lecture seule
adModeWrite 2 Écriture seule
adModeReadWrite 3 Lecture et écriture
adModeShareDenyRead 4 Ouverture en lecture interdite pour les utilisateurs autorisés en lecture seule
adModeShareDenyWrite 8 Ouverture interdite pour les utilisateurs autorisés en écriture seule
adModeShareExclusive 12 Ouverture interdite aux autres utilisateurs
adModeShareDenyNone 16 Les autres utilisateurs peuvent ouvrir en lecture/écriture

Définir correctement cette propriété permet dans bien des cas de simplifier les éventuels conflits.

VII-A-4. Collection Errors

Toutes les erreurs de fournisseur créent un objet Error qui vient s'ajouter à la collection Errors de l'objet Connection. Il faut bien garder à l'esprit que ce ne sont que les erreurs du fournisseur, les autres erreurs ADO se gèrent de façon standard. Cette collection Errors se remplie pour une opération, si une erreur survient lors d'une opération suivante, l'ancienne collection est remplacée par la nouvelle.

Dans certains cas, le fournisseur envoie des avertissement dans la collection Errors, il est souvent conseillé de vider la collection Errors à l'aide de la méthode Clear avant d'utiliser les méthodes Resync, CancelBatch et UpdateBatch sur l'objet Recordset.

VII-A-5. Evènements de connexion

A l'ouverture de la connexion, on peut décider si celle-ci s'ouvre de façon asynchrone en valorisant le paramètre "Options" de la méthode Open à adAsyncConnect.

Les évènements de l'objet Connection sont :

BeginTransComplete, CommitTransComplete, et RollbackTransComplete pour les transactions

WillConnect, ConnectComplete et Disconnect pour l'ouverture et la fermeture

InfoMessage pour la gestion des erreurs

VII-A-5-a. WillExecute & ExecuteComplete

Ces évènements se déclenche avant et après l'exécution d'une commande, implicite ou non. En clair, ces événements se produisent sur l'appel de Connection.Execute, Command.Execute et Recordset.Open.

 
Sélectionnez
Private Sub Connection_WillExecute(Source As String, CursorType As ADODB.CursorTypeEnum, _ 
 	LockType As ADODB.LockTypeEnum, Options As Long, adStatus As ADODB.EventStatusEnum, ByVal pCommand As ADODB.Command, _
 	ByVal pRecordset As ADODB.Recordset, ByVal pConnection As ADODB.Connection)

Private Sub Connection_ExecuteComplete(ByVal RecordsAffected As Long, _ 
	 ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum,  _ 
	 ByVal pCommand As ADODB.Command, ByVal pRecordset As ADODB.Recordset, _ 
 	 ByVal pConnection As ADODB.Connection)

pConnection doit toujours contenir une référence à une connexion valide.

Si l'événement est dû à Connection.Execute, pCommand et pRecordset sont à "Nothing".

Si l'événement est dû à Command.Execute, pCommand est la référence de l'objet Command et pRecordset vaut "Nothing".

Si l'événement est dû à Recordset.Open, pCommand vaut "Nothing" et pRecordset est la référence de l'objet Recordset.

VII-B. L'objet Command

Pour ceux d'entre vous qui avez lu l'article "Utiliser le modèle ADOX avec Visual Basic" vous allez retrouver sensiblement le même chapitre, un peu plus étoffé et portant sur des axes différents.

Beaucoup de programmeur n'utilise pas l'objet Command avec ADO préférant travailler directement avec l'objet Recordset. Pourtant l'utilisation de cet objet peut être indispensable lorsqu'on souhaite travailler avec des requêtes paramétrées ou pour utiliser directement des requêtes actions. Nous allons donc aborder l'objet Command de façon assez détaillée sous l'angle suivant :

  • Utilisation de Command pour utiliser des requêtes paramétrées
  • Utilisation de Command avec des requêtes actions

Nous allons commencer par voir l'objet Command en détail.

VII-B-1. Généralités

Un objet command représente une commande spécifique à exécuter sur une source de données. Ceci peut être une instruction SQL ou une procédure stockée. Cet objet peut être une requête/procédure stockée dans la base ou créé à l'exécution. Un objet Command dépend toujours d'une connection soit créée spécifiquement pour cette commande, soit d'une connection déjà existante.

VII-B-2. Propriétés

ActiveConnection

Définit la connection utilisé pour l'objet Command. Cette propriété doit être passée à Nothing avant de changer la connection d'un objet Command. Comme les objets Command héritent de certaines propriétés de la connection, faites attention au paramétrage de celle-ci.

CommandText

La propriété CommandText contient le texte de la commande à exécuter. Ce texte peut être le nom d'une requête stockée, une chaîne SQL etc…

CommandTimeout

La valeur est en seconde. S'applique en général sur l'objet connection

CommandType

Donne le type de la commande. Cette propriété est très importante. En effet, il y aura une erreur récupérable si le paramètre donné est faux. De plus ne pas valoriser correctement cette propriété peut dégrader fortement les performances. Les valeurs peuvent êtres

Constante Valeur Description
adCmdText 1 CommandText correspond à la définition textuelle d'une commande ou d'un appel de procédure stockée
adCmdTable 2 CommandText correspond au nom de table dont les colonnes sont toutes renvoyées par une requête SQL générée en interne.
adCmdTableDirect 512 CommandText correspond à un nom de table dont les colonnes sont toutes renvoyées.
adCmdStoredProc 4 CommandText correspond au nom d'une procédure stockée.
adCmdUnknown 8 Valeur utilisée par défaut. Le type de commande de la propriété CommandText est inconnu
adCmdFile 256 CommandText correspond au nom de fichier d'un Recordset permanent
adExecuteNoRecords 128 CommandText correspond à une commande ou une procédure stockée qui ne renvoie pas de ligne (par exemple, une commande qui insère uniquement des données). Si des lignes sont extraites, elles ne sont pas prises en compte et ne sont pas retournées. Toujours associée à adCmdText ou adCmdStoredProc

Attention toutefois, une procédure stockée peut être différemment interprétée selon les SGBD. Voir aussi la rubrique "Parameters".

NamedParameters

Défini si le nom des paramètres sont passés au fournisseur, ce qui lui permet de ne pas avoir à les interpréter dans l'ordre de leur création.

Prepared

Détermine si une commande doit être Pré-compilée. N'est utile que si la commande doit être exécutée plusieurs fois. Attention, certains fournisseurs n'acceptent pas cette modification sans toutefois déclencher d'erreur.

State

Renvoie l'état de la commande (ouverte ou fermée)

VII-B-3. Méthodes

Cancel

Annule l'exécution de la commande si celle-ci est asynchrone.

Execute

Execute la commande. De la forme :

command.Execute RecordsAffected, Parameters, Options

RecordsAffected renvoie le nombre d'enregistrements affectés par la commande. Ceci n'est vrai que pour une requète action ou pour l'appel d'une procédure d'action. Le paramètre n'est pas valorisé avec le nombre d'enregistrement extrait si la commande renvoie un recordset.

Parameters est un tableau contenant les paramètres (pour les requêtes/procédures paramétrées évidemment)

Option est identique a ce qui est décrit dans la méthode Open de l'objet Recordset.

Nous avons là plusieurs cas qui nous intéressent :

  • On utilise toujours Command.Execute ou Connection.Execute pour utiliser des requêtes actions.
  • Pour récupérer un recordset de l'objet Command, on peut soit passer la commande dans la méthode Open du recordset, soit affecter les enregistrements renvoyés dans un recordset.

Regardons le code suivant :

 
Sélectionnez
Dim Cnn1 As ADODB.Connection, MonRs As ADODB.Recordset, MaCommand As ADODB.Command

Set Cnn1 = New ADODB.Connection
Cnn1.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=d:\biblio.mdb ;User Id=Admin; Password="
Set MaCommand = New ADODB.Command
With MaCommand
    .ActiveConnection = Cnn1
    .CommandText = "SELECT * FROM Authors"
    Set MonRs = MaCommand.Execute
End With
MonRs.Close
Set MonRs = Nothing
Set MonRs = New ADODB.Recordset
MonRs.Open MaCommand, , adOpenKeyset, adLockOptimistic, adCmdText

J'utilise les deux méthodes que je vous ai données plus haut. Notez toutefois que dans le Command.Execute je n'ai pas défini le curseur. J'obtiens donc un curseur côté serveur en avant seulement et en lecture seule. Supposons que je paramètre mon Recordset au préalable :

 
Sélectionnez
Set MonRs = New ADODB.Recordset
With MonRs
    .CursorLocation = adUseClient
    .CursorType = adOpenStatic
    .LockType = adLockOptimistic
End With
Set MonRs = MaCommand.Execute

J'obtiendrais pourtant le même curseur qu'avec le code précédent. Cela vient du fait que lors de la création d'un recordset à l'aide de la méthode Execute, que ce soit sur l'objet Connection ou sur l'objet Command, hérite d'un curseur défini par la connexion. Selon la valeur de la propriété CursorLocation de l'objet Connection, vous obtiendrez soit un curseur en avant seulement en lecture seule (serveur) soit un curseur statique en lecture seule (Client). Le recordset sera toujours en lecture seule.

CreateParameter

Sert à créer un paramètre (voir explications plus loin).

De la forme command.CreateParameter (Name, Type, Direction, Size, Value)

Attention à ne pas faire une erreur courante avec cette méthode. Celle-ci crée un paramètre mais ne l'ajoute pas à la collection Parameters de l'objet Command. Ceci est d'ailleurs indispensable afin de pouvoir valoriser d'autres propriétés avant l'ajout.

VII-B-4. Collection Parameters

Généralités

Il faut déjà faire attention, pour les utilisateurs d'autres SGBD qu'Access à bien faire la différence entre procédure stockée et requête paramétrée.

Quoique regroupés dans la même collection, il existe deux types de paramètres. Les paramètres d'entrée, attendus par la procédure/requête pour pouvoir s'exécuter, et les paramètres de sorties qui peuvent êtres renvoyés par une procédure. Il convient de faire attention avec ceux-ci, une connection n'acceptant jamais plus de deux objets Command ayant des paramètres de sorties.

Quelques méthodes de la collection

Append

Ajoutes un paramètre à la collection. De la forme

Command.Parameters .Append Name, Type, DefinedSize, Attrib

Il est possible d'utiliser la méthode CreateParameter dans le Append. Vous devez avoir typé votre paramètre avant ou lors de l'ajout à la collection. Il est préférable de valoriser votre paramètre avant de l'ajouter à la collection afin de ne pas solliciter le fournisseur.

Delete

Enlève un paramètre de la collection. On doit spécifier soit le nom, soit l'index du paramètre à retirer.

VII-B-5. Objet Parameter

Propriétés

Attributes

Précise si le paramètre accepte les valeurs signées, binaires ou NULL.

Direction

Définit si le paramètre est un paramètre d'entrée, de sortie ou de retour. Attention de ne pas confondre un paramètre de retour(adParamReturnValue) qui est l'entier éventuellement renvoyé par une procédure (dans le Return) d'un paramètre de sortie (adParamOutput) qui est le paramètre renvoyé par une procédure.

Name

Défini le nom du paramètre. N'est pas obligatoire

NumericScale

Donne la précision (nombre de chiffres à droite de la virgule) d'un paramètre numérique.

Size

Donne la taille en octet d'un paramètre dont le type est potentiellement de longueur variable (par exemple String). Ce paramètre est obligatoire pour les types de longueur indéterminé (String, Variant).

Elle doit être toujours valorisée avant ou lors de l'ajout à la collection.

Type

Comme son nom l'indique !

Ne vous emmêlez pas les pinceaux entre les chaînes adVarChar et les chaînes Unicode adVarWChar

Value

De manière générale, valorisez cette propriété après l'ajout à la collection.

Méthode

AppendChunk

Permet d'accéder aux textes ou binaires longs.

VII-B-6. Exemple

Requêtes paramétrées

Nous allons voir ici un exemple d'utilisation de requête paramétrée.

Prenons la requête stockée nommée ReqFerie définie comme :

 
Sélectionnez
PARAMETERS DateCib DateTime;
SELECT tblFerie.DateFer
FROM tblFerie
WHERE (((tblFerie.DateFer)>DateValue([DateCib])))
ORDER BY tblFerie.DateFer;

La fonction suivante crée un recordset en utilisant l'objet Command.

 
Sélectionnez
Private Sub Command5_Click()
Dim cnn1 As ADODB.Connection, Comm1 As ADODB.Command, Param1 As Parameter, MonRecordset As ADODB.Recordset

Set cnn1 = New ADODB.Connection
With cnn1
    .Provider = "Microsoft.Jet.OLEDB.4.0;"
    .ConnectionTimeout = 30
    .CursorLocation = adUseClient
    .IsolationLevel = adXactChaos
    .Mode = adModeShareExclusive
    .Properties("Jet OLEDB:System database") = "D:\User\jmarc\tutorial\ADOX\system.mdw"
    .Open "Data Source=D:\User\jmarc\tutorial\ADOX\baseheb.mdb ;User Id=Admin; Password="
End With
Set Comm1 = New ADODB.Command
With Comm1
    .ActiveConnection = cnn1
    .CommandType = adCmdStoredProc
    .CommandText = "ReqFerie"
End With
Set Param1 = New Parameter
With Param1
    .Direction = adParamInput
    .Type = adDate
    .Name = "DateCib"
End With
Comm1.Parameters.Append Param1
Comm1("DateCib").Value = #1/1/2002#
Set MonRecordset = Comm1.Execute
    
End Sub

Requête action

On peut aussi utiliser aussi l'objet Command pour exécuter des requêtes actions sur la source de données. En général, comme celles-ci sont rarement utilisées plusieurs fois dans le même code, on utilise plus souvent l'objet Connection, ce qui permet de tout passer dans une ligne, tel que :

 
Sélectionnez
Cnn1.Execute "DELETE * FROM Authors WHERE [year Born]=1938", , adExecuteNoRecords

Néanmoins on peut aussi utiliser l'objet Command.

 
Sélectionnez
With Comm1
    .ActiveConnection = cnn1
    .CommandType = adCmdText
    .CommandText = "UPDATE Authors SET [Year Born]= [Year Born]+1"
End With
Comm1.Execute

On trouve par contre beaucoup plus souvent l'usage de requête stockée paramétrée avec l'objet command. Par exemple:

 
Sélectionnez
Dim cnn1 As ADODB.Connection, Comm1 As ADODB.Command, Param1 As Parameter, Param2 As Parameter, MonRecordset As ADODB.Recordset

Set cnn1 = New ADODB.Connection
With cnn1
    .Provider = "Microsoft.Jet.OLEDB.4.0;"
    .ConnectionTimeout = 30
    .CursorLocation = adUseClient
    .Open "Data Source=D:\basehebdo.mdb ;User Id=Admin; Password="
End With
cnn1.BeginTrans
Set Comm1 = New ADODB.Command
With Comm1
    .ActiveConnection = cnn1
    .CommandType = adCmdText
    .CommandText = "PARAMETERS DateCib DateTime, BancCib Text;" & _
		 "DELETE * From tblAnomalie WHERE tblAnomalie.NumBanc=[BancCib] AND tblAnomalie.DatDimanche>=[DateCib];"
    .NamedParameters = True
End With
Set Param1 = New Parameter
With Param1
    .Direction = adParamInput
    .Type = adDate
    .Name = "DateCib"
End With
Set Param2 = New Parameter
With Param2
    .Direction = adParamInput
    .Type = adVarWChar
    .Size = 3
    .Name = "BancCib"
End With
Comm1.Parameters.Append Param1
Comm1.Parameters.Append Param2
Comm1("BancCib").Value = "S01"
Comm1("DateCib").Value = #1/1/2002#
Comm1.Execute
If MsgBox("valider la transaction", vbYesNo) = vbYes Then
    cnn1.CommitTrans
Else
    cnn1.RollbackTrans
End If

L'avantage de ce genre d'utilisation repose sur le fait qu'un nouvel appel d'Execute avec de nouvelles valeurs de paramètres est immédiatement accessible. Ainsi

 
Sélectionnez
Comm1.Execute , Array(#1/1/2002#, "S04"), adCmdText + adExecuteNoRecords

Est une réutilisation aisée de ma commande.


précédentsommairesuivant

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

  

Copyright © 2003 bidou. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.