IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

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 faites 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. À 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 remplit 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 avertissements 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. Événements de connexion

À 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 et ExecuteComplete

Ces événements se déclenchent 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 ont 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 programmeurs n'utilisent 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éée à l'exécution. Un objet Command dépend toujours d'une connexion soit créée spécifiquement pour cette commande, soit d'une connexion déjà existante.

VII-B-2. Propriétés

ActiveConnection

Définit la connexion utilisée pour l'objet Command. Cette propriété doit être passée à Nothing avant de changer la connexion d'un objet Command. Comme les objets Command héritent de certaines propriétés de la connexion, 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éfinit si le nom des paramètres est passé 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'enregistrements extraits 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 être 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

Ajoute 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éfinit 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ée (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

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.