Partage via


Programmation ADO Visual C++

La référence de l’API ADO décrit les fonctionnalités de l’interface de programmation d’applications ADO (API) à l’aide d’une syntaxe similaire à Microsoft Visual Basic. Bien que l’audience prévue soit tous les utilisateurs, les programmeurs ADO utilisent différents langages tels que Visual Basic, Visual C++ (avec et sans la directive #import) et Visual J++ (avec le package de classe ADO/WFC).

Note

Microsoft a terminé la prise en charge de Visual J++ en 2004.

Pour prendre en charge cette diversité, les index de syntaxe ADO pour Visual C++ fournissent une syntaxe spécifique au langage Visual C++ avec des liens vers des descriptions courantes des fonctionnalités, des paramètres, des comportements exceptionnels, etc., dans la référence de l’API.

ADO est implémenté avec des interfaces COM (Component Object Model). Toutefois, il est plus facile pour les programmeurs d’utiliser COM dans certains langages de programmation que d’autres. Par exemple, presque tous les détails d’utilisation de COM sont gérés implicitement pour les programmeurs Visual Basic, tandis que les programmeurs Visual C++ doivent assister à ces détails eux-mêmes.

Les sections suivantes résument les détails pour les programmeurs C et C++ utilisant ADO et la directive #import. Il se concentre sur les types de données spécifiques à COM (Variant, BSTRet SafeArray) et à la gestion des erreurs (_com_error).

Utilisation de la directive du compilateur #import

La directive du compilateur #import Visual C++ simplifie l’utilisation des méthodes et propriétés ADO. La directive prend le nom d’un fichier contenant une bibliothèque de types, comme le .dll ADO (Msado15.dll), et génère des fichiers d’en-tête contenant des déclarations typedef, des pointeurs intelligents pour les interfaces et des constantes énumérées. Chaque interface est encapsulée ou enveloppée dans une classe.

Pour chaque opération dans une classe (autrement dit, une méthode ou un appel de propriété), il existe une déclaration pour appeler l’opération directement (autrement dit, la forme « brute » de l’opération) et une déclaration pour appeler l’opération brute et lever une erreur COM si l’opération ne parvient pas à s’exécuter correctement. Si l’opération est une propriété, il existe généralement une directive du compilateur qui crée une autre syntaxe pour l’opération qui a une syntaxe telle que Visual Basic.

Les opérations qui récupèrent la valeur d'une propriété ont des noms de la forme GetProperty. Les opérations qui définissent la valeur d’une propriété ont des noms de formulaire, PutProperty. Les opérations qui définissent la valeur d’une propriété avec un pointeur vers un objet ADO ont des noms de formulaire, PutRefProperty.

Vous pouvez acquérir ou assigner une propriété avec des appels de ces formes :

variable = objectPtr->GetProperty(); // get property value   
objectPtr->PutProperty(value);       // set property value  
objectPtr->PutRefProperty(&value);   // set property with object pointer  

Utilisation des directives de propriété

La directive __declspec(property...) compilateur est une extension de langage C spécifique à Microsoft qui déclare une fonction utilisée comme propriété pour avoir une autre syntaxe. Par conséquent, vous pouvez définir ou obtenir des valeurs d’une propriété d’une manière similaire à Visual Basic. Par exemple, vous pouvez définir et obtenir une propriété de cette façon :

objectPtr->property = value;        // set property value  
variable = objectPtr->property;     // get property value  

Notez que vous n’avez pas besoin de coder :

objectPtr->PutProperty(value);      // set property value  
variable = objectPtr->GetProperty;  // get property value  

Le compilateur génère l’appel Get-approprié, Put-, ou PutRefProperty en fonction de la syntaxe alternative déclarée et si la propriété est en cours de lecture ou d’écriture.

La directive de compilateur __declspec(propriété...) ne peut déclarer get, set, ou get et set comme syntaxe alternative d'une fonction. Les opérations en lecture seule ont une déclaration de obtenir ; Les opérations en écriture seule ont uniquement une déclaration placer ; les opérations de lecture et d’écriture ont à la fois des obtenir et placer des déclarations de.

Seules deux déclarations sont possibles avec cette directive ; toutefois, chaque propriété peut avoir trois fonctions de propriété : GetProperty, PutPropertyet PutRefProperty. Dans ce cas, seules deux formes de la propriété ont la syntaxe alternative.

Par exemple, l’objet Command ActiveConnection est déclaré avec une autre syntaxe pour GetActiveConnection et PutRefActiveConnection. La PutRef- syntaxe est un bon choix, car dans la pratique, vous souhaiterez généralement placer un objet Connection ouvert (autrement dit, un pointeur d’objet Connection) dans cette propriété. En revanche, l'objet Recordset dispose des opérations Get-, Put-, et PutRefavec ActiveConnection, mais pas de syntaxe alternative.

Collections, méthode GetItem et propriété Item

ADO définit plusieurs collections, notamment Fields, Parameters, Propertieset Errors. Dans Visual C++, la méthode GetItem(index) retourne un membre de la collection. Index est un Variant, dont la valeur est un index numérique du membre dans la collection ou une chaîne contenant le nom du membre.

La directive de compilateur __declspec(property...) déclare la propriété Item comme une syntaxe alternative à la méthode fondamentale GetItem() de chaque collection. La syntaxe alternative utilise des crochets et ressemble à une référence de tableau. En général, les deux formes ressemblent à ce qui suit :

  
      collectionPtr->GetItem(index);  
collectionPtr->Item[index];  

Par exemple, affectez une valeur à un champ d’un objet Recordset, nommé rs, dérivé de la table auteurs de la base de données pubs. Utilisez la propriété Item() pour accéder au troisième champ de l’objet Recordsetcollection Fields (les collections sont indexées à partir de zéro ; supposons que le troisième champ est nommé au_fname). Appelez ensuite la méthode Value() sur l’objet Field pour affecter une valeur de chaîne.

Cela peut être exprimé en Visual Basic de quatre manières suivantes (les deux derniers formulaires sont uniques à Visual Basic ; d’autres langages n’ont pas d’équivalents) :

rs.Fields.Item(2).Value = "value"  
rs.Fields.Item("au_fname").Value = "value"  
rs(2) = "value"  
rs!au_fname = "value"  

L’équivalent en Visual C++ aux deux premières formes ci-dessus est :

rs->Fields->GetItem(long(2))->PutValue("value");   
rs->Fields->GetItem("au_fname")->PutValue("value");  

-ou- (la syntaxe alternative de la propriété Value est également affichée)

rs->Fields->Item[long(2)]->Value = "value";  
rs->Fields->Item["au_fname"]->Value = "value";  

Pour obtenir des exemples d’itération dans une collection, consultez la section « Collections ADO » de « Référence ADO ».

types de données COM-Specific

En général, tout type de données Visual Basic que vous trouvez dans la référence de l’API ADO a un équivalent Visual C++. Il s’agit notamment de types de données standard tels que caractères non signés pour un d’octet Visual Basic, court pour entier entier et long pour long. Regardez dans l’index de syntaxe pour voir exactement ce qui est requis pour les opérandes d’une méthode ou d’une propriété donnée.

Les exceptions à cette règle sont les types de données spécifiques à COM : Variant, BSTRet SafeArray.

Variante

Un Variant est un type de données structuré qui contient un membre valeur et un membre de type de données. Un Variant peut contenir un large éventail d’autres types de données, notamment un autre Variant, BSTR, Boolean, IDispatch ou IUnknown pointer, currency, date, et ainsi de suite. COM fournit également des méthodes qui facilitent la conversion d’un type de données en un autre.

La classe _variant_t encapsule et gère le type de données Variant.

Lorsque la référence de l’API ADO indique une méthode ou un opérande de propriété prend une valeur, cela signifie généralement que la valeur est passée dans un _variant_t.

Cette règle est explicitement vraie lorsque la section paramètres dans les thématiques de la référence d’API ADO indique qu’un opérande est un Variant. Il y a une exception lorsque la documentation indique explicitement que l'opérande utilise un type de données standard, tel que long ou octet, ou une énumération. Une autre exception est lorsque l’opérande prend un string.

BSTR

Un BSTR (Basic STRing) est un type de données structuré qui contient une chaîne de caractères et la longueur de la chaîne. COM fournit des méthodes pour allouer, manipuler et désallouer un BSTR.

La classe _bstr_t encapsule et gère le type de données BSTR.

Lorsque la référence de l’API ADO indique qu'une méthode ou qu'une propriété prend une valeur String, cela signifie que la valeur est sous la forme d’un _bstr_t.

Conversion des classes _variant_t et _bstr_t

Il n’est souvent pas nécessaire de coder explicitement une _variant_t ou _bstr_t dans un argument d’une opération. Si la classe _variant_t ou _bstr_t a un constructeur qui correspond au type de données de l’argument, le compilateur génère les _variant_t ou _bstr_tappropriés.

Toutefois, si l’argument est ambigu, autrement dit, le type de données de l’argument correspond à plusieurs constructeurs, vous devez convertir l’argument avec le type de données approprié pour appeler le constructeur correct.

Par exemple, la déclaration de la méthode Recordset ::Open est la suivante :

    HRESULT Open (  
        const _variant_t & Source,  
        const _variant_t & ActiveConnection,  
        enum CursorTypeEnum CursorType,  
        enum LockTypeEnum LockType,  
        long Options );  

L’argument ActiveConnection prend une référence à un _variant_t, que vous pouvez coder en tant que chaîne de connexion ou pointeur vers un objet Connection ouvert.

La _variant_t correcte sera construite implicitement si vous passez une chaîne telle que «DSN=pubs;uid=MyUserName;pwd=<password>;», ou un pointeur tel que «(IDispatch *) pConn».

Note

Si vous vous connectez à un fournisseur de sources de données qui prend en charge l’authentification Windows, vous devez spécifier Trusted_Connection=oui ou sécurité intégrée = SSPI au lieu des informations d’ID d’utilisateur et de mot de passe dans la chaîne de connexion.

Vous pouvez également coder explicitement un _variant_t contenant un pointeur tel que «_variant_t((IDispatch *) pConn, true)». Le cast (IDispatch *)résout l’ambiguïté avec un autre constructeur qui prend un pointeur vers l'interface IUnknown.

Il s’agit d’un fait crucial, bien que rarement mentionné, que ADO est une interface IDispatch. Chaque fois qu’un pointeur vers un objet ADO doit être passé en tant que Variant, ce pointeur doit être casté en tant que pointeur vers une interface IDispatch.

Le dernier cas code explicitement le deuxième argument booléen du constructeur avec sa valeur par défaut facultative de true. Cet argument entraîne le constructeur du Variant à appeler sa méthode AddRef(), qui compense l'appel automatique d'ADO à la méthode _variant_t::Release() lorsque l'appel de méthode ou de propriété ADO est terminé.

SafeArray

Un SafeArray est un type de données structuré qui contient un tableau d’autres types de données. Un SafeArray est appelé sécurisé, car il contient des informations sur les limites de chaque dimension de tableau et limite l’accès aux éléments de tableau dans ces limites.

Lorsque la référence de l’API ADO indique qu’une méthode ou une propriété prend ou retourne un tableau, cela signifie que la méthode ou la propriété accepte ou retourne un SafeArray, et non un tableau C/C++ natif.

Par exemple, le deuxième paramètre de l'objet Connection de la méthode OpenSchema nécessite un tableau de valeurs Variant. Ces valeurs Variant doivent être passées en tant qu’éléments d’un SafeArray, et que SafeArray doivent être définies comme valeur d’un autre Variant. C'est cet autre Variant qui est passé en tant que deuxième argument de OpenSchema.

Comme d’autres exemples, le premier argument de la méthode Find est un variant dont la valeur est un SafeArrayunidimensionnel ; chacun des arguments facultatifs de AddNew est un SafeArrayunidimensionnel ; et la valeur de retour de la méthode getRows est une variant dont la valeur est un SafeArraybidimensionnel.

Paramètres manquants et par défaut

Visual Basic autorise les paramètres manquants dans les méthodes. Par exemple, l'objet Recordset méthode Open a cinq paramètres, mais vous pouvez ignorer les paramètres intermédiaires et laisser de côté les paramètres de fin. Une BSTR par défaut ou variant sera substituée en fonction du type de données de l’opérande manquant.

En C/C++, tous les opérandes doivent être spécifiés. Si vous souhaitez spécifier un paramètre manquant dont le type de données est une chaîne, spécifiez un _bstr_t contenant une chaîne Null. Si vous souhaitez spécifier un paramètre manquant dont le type de données est un Variant, spécifiez un _variant_t avec une valeur de DISP_E_PARAMNOTFOUND et un type de VT_ERROR. Vous pouvez également spécifier la constante équivalente _variant_t, vtMissing, fournie par la directive #import.

Trois méthodes sont des exceptions à l’utilisation classique de vtMissing. Il s’agit des méthodes Execute des objets connection et Command, ainsi que la méthode NextRecordset de l’objet Recordset. Voici leurs signatures :

_RecordsetPtr <A HREF="mdmthcnnexecute.htm">Execute</A>( _bstr_t CommandText, VARIANT * RecordsAffected,   
        long Options );  // Connection  
_RecordsetPtr <A HREF="mdmthcmdexecute.htm">Execute</A>( VARIANT * RecordsAffected, VARIANT * Parameters,   
        long Options );  // Command  
_RecordsetPtr <A HREF="mdmthnextrec.htm">NextRecordset</A>( VARIANT * RecordsAffected );  // Recordset  

Les paramètres, RecordsAffected et Parameters, sont des pointeurs vers un Variant. Parameters est un paramètre d’entrée qui spécifie l’adresse d’un Variant contenant un seul paramètre, ou tableau de paramètres, qui modifie la commande en cours d’exécution. RecordsAffected est un paramètre de sortie qui spécifie l’adresse d’un Variant, où le nombre de lignes affectées par la méthode est retourné.

Dans l’objet CommandExecute, indiquez qu’aucun paramètre n’est spécifié en définissant Paramètres sur &vtMissing (recommandé) ou sur le pointeur Null (autrement dit, NULL ou zéro (0)). Si Parameters est défini sur le pointeur Null, la méthode remplace en interne l’équivalent de vtMissing, puis termine l’opération.

Dans toutes les méthodes, indiquez que le nombre d’enregistrements affectés ne doit pas être retourné en définissant RecordsAffected au pointeur Null. Dans ce cas, le pointeur Null n’est pas tant un paramètre manquant qu’une indication que la méthode doit ignorer le nombre d’enregistrements affectés.

Ainsi, pour ces trois méthodes, il est valide de coder quelque chose comme :

pConnection->Execute("commandText", NULL, adCmdText);   
pCommand->Execute(NULL, NULL, adCmdText);  
pRecordset->NextRecordset(NULL);  

Gestion des erreurs

Dans COM, la plupart des opérations retournent un code de retour HRESULT qui indique si une fonction s’est terminée correctement. La directive #import génère du code wrapper autour de chaque méthode ou propriété « brute » et vérifie le HRESULT retourné. Si HRESULT indique un échec, le code wrapper lève une erreur COM en appelant _com_issue_errorex() avec le code de retour HRESULT en tant qu’argument. Les objets d’erreur COM peuvent être interceptés dans un essayer-intercepter bloc. (Par souci d’efficacité, capturez une référence à un objet _com_error.)

N’oubliez pas qu’il s’agit d’erreurs ADO : elles résultent de l’échec de l’opération ADO. Les erreurs retournées par le fournisseur sous-jacent apparaissent sous la forme d'objets Error dans l'objet de connexion Connection de la collection Errors.

La directive #import crée uniquement des routines de gestion des erreurs pour les méthodes et les propriétés déclarées dans le .dllADO . Toutefois, vous pouvez tirer parti de ce même mécanisme de gestion des erreurs en écrivant votre propre macro de vérification des erreurs ou fonction inline. Consultez la rubrique extensions Visual C++ou le code des sections suivantes pour obtenir des exemples.

Équivalents Visual C++ des conventions Visual Basic

Voici un résumé de plusieurs conventions dans la documentation ADO, codées en Visual Basic, ainsi que leurs équivalents dans Visual C++.

Déclaration d’un objet ADO

Dans Visual Basic, une variable objet ADO (dans ce cas pour un objet Recordset) est déclarée comme suit :

Dim rst As ADODB.Recordset  

La clause , «ADODB.Recordset», est le ProgID de l’objet Recordset tel que défini dans le Registre. Une nouvelle instance d’un objet Record est déclarée comme suit :

Dim rst As New ADODB.Recordset  

-ou-

Dim rst As ADODB.Recordset  
Set rst = New ADODB.Recordset  

Dans Visual C++, la directive #import génère des déclarations de type pointeur intelligent pour tous les objets ADO. Par exemple, une variable qui pointe vers un objet _Recordset est de type _RecordsetPtr, et est déclarée comme suit :

_RecordsetPtr  rs;  

Une variable qui pointe vers une nouvelle instance d’un objet _Recordset est déclarée comme suit :

_RecordsetPtr  rs("ADODB.Recordset");  

-ou-

_RecordsetPtr  rs;  
rs.CreateInstance("ADODB.Recordset");  

-ou-

_RecordsetPtr  rs;  
rs.CreateInstance(__uuidof(_Recordset));  

Une fois que la méthode CreateInstance est appelée, la variable peut être utilisée comme suit :

rs->Open(...);  

Notez que dans un cas, l’opérateur «.» est utilisé comme si la variable était une instance d’une classe (rs.CreateInstance), et dans un autre cas, l’opérateur «->» est utilisé comme si la variable était un pointeur vers une interface (rs->Open).

Une variable peut être utilisée de deux façons, car l’opérateur «->» est surchargé pour permettre à une instance d’une classe de se comporter comme un pointeur vers une interface. Un membre de classe privée de la variable d’instance contient un pointeur vers l’interface _Recordset ; l’opérateur «->» retourne ce pointeur ; et le pointeur retourné accède aux membres de l’objet _Recordset.

Codage d’un paramètre manquant - Chaîne

Lorsque vous devez coder une chaîne manquante String operand en Visual Basic, vous omettez simplement l’opérande. Vous devez spécifier l’opérande dans Visual C++. Codez un _bstr_t qui a une chaîne vide sous forme de valeur.

_bstr_t strMissing(L"");  

Codage d’un paramètre manquant - Variant

Lorsque vous devez coder un opérande Variant manquant en Visual Basic, il vous suffit d’omettre l’opérande. Vous devez spécifier tous les opérandes dans Visual C++. Codez un paramètre de variante manquant avec un _variant_t défini sur la valeur spéciale DISP_E_PARAMNOTFOUND et le type VT_ERROR. Vous pouvez également spécifier vtMissing, qui est une constante équivalente prédéfinie fournie par la directive #import.

_variant_t  vtMissingYours(DISP_E_PARAMNOTFOUND, VT_ERROR);   

-ou utiliser -

...vtMissing...;  

Déclaration d’un variant

Dans Visual Basic, un variant est déclaré avec l’instruction Dim comme suit :

Dim VariableName As Variant  

Dans Visual C++, déclarez une variable en tant que type _variant_t. Quelques déclarations schématiques de _variant_t sont présentées ci-dessous.

Note

Ces déclarations donnent simplement une idée approximative de ce que vous coderiez dans votre propre programme. Pour plus d’informations, consultez les exemples ci-dessous et la documentation Visual C++.

_variant_t  VariableName(value);  
_variant_t  VariableName((data type cast) value);  
_variant_t  VariableName(value, VT_DATATYPE);  
_variant_t  VariableName(interface * value, bool fAddRef = true);  

Utilisation de tableaux de variantes

Dans Visual Basic, les tableaux de variants peuvent être codés avec l’instruction Dim, ou vous pouvez utiliser la fonction Array, comme illustré dans l’exemple de code suivant :

Public Sub ArrayOfVariants  
Dim cn As ADODB.Connection  
Dim rs As ADODB.Recordset  
Dim fld As ADODB.Field  
  
    cn.Open "DSN=pubs"  
    rs = cn.OpenSchema(adSchemaColumns, _  
        Array(Empty, Empty, "authors", Empty))  
    For Each fld in rs.Fields  
        Debug.Print "Name = "; fld.Name  
    Next fld  
    rs.Close  
    cn.Close  
End Sub  

L’exemple Visual C++ suivant illustre l’utilisation d’un SafeArray utilisé avec un _variant_t.

Notes

Les notes suivantes correspondent aux sections commentées de l’exemple de code.

  1. Une fois de plus, la fonction inline TESTHR() est définie pour tirer parti du mécanisme de gestion des erreurs existant.

  2. Vous n’avez besoin que d’un tableau unidimensionnel, donc vous pouvez utiliser SafeArrayCreateVector, au lieu de la déclaration générale SAFEARRAYBOUND et la fonction SafeArrayCreate. Voici ce que ce code ressemblerait à l’aide de SafeArrayCreate:

       SAFEARRAYBOUND   sabound[1];  
       sabound[0].lLbound = 0;  
       sabound[0].cElements = 4;  
       pSa = SafeArrayCreate(VT_VARIANT, 1, sabound);  
    
  3. Le schéma identifié par la constante énumérée, adSchemaColumns, est associé à quatre colonnes de contrainte : TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME et COLUMN_NAME. Par conséquent, un tableau de valeurs de Variant avec quatre éléments est créé. Ensuite, une valeur de contrainte qui correspond à la troisième colonne, TABLE_NAME, est spécifiée.

    Le jeu d’enregistrements retourné se compose de plusieurs colonnes, dont un sous-ensemble correspond aux colonnes de contrainte. Les valeurs des colonnes de contrainte pour chaque ligne retournée doivent être identiques aux valeurs de contrainte correspondantes.

  4. Ceux qui connaissent SafeArrays peuvent être surpris que SafeArrayDestroy() n’est pas appelé avant la sortie. En fait, l'appel à SafeArrayDestroy() dans ce cas entraînera une exception au moment de l'exécution. La raison est que le destructeur de vtCriteria appelle VariantClear() lorsque le _variant_t sort de portée, ce qui libérera le SafeArray. Appeler SafeArrayDestroysans effacer manuellement le _variant_tamènerait le destructeur à essayer de libérer un pointeur SafeArray non valide.

    Si SafeArrayDestroy était appelée, le code se présenterait comme suit :

          TESTHR(SafeArrayDestroy(pSa));  
       vtCriteria.vt = VT_EMPTY;  
          vtCriteria.parray = NULL;  
    

    Toutefois, il est beaucoup plus simple de laisser le _variant_t gérer le SafeArray.

// Visual_CPP_ADO_Prog_1.cpp  
// compile with: /EHsc  
#import "msado15.dll" no_namespace rename("EOF", "EndOfFile")  
  
// Note 1  
inline void TESTHR( HRESULT _hr ) {   
   if FAILED(_hr)   
      _com_issue_error(_hr);   
}  
  
int main() {  
   CoInitialize(NULL);  
   try {  
      _RecordsetPtr pRs("ADODB.Recordset");  
      _ConnectionPtr pCn("ADODB.Connection");  
      _variant_t vtTableName("authors"), vtCriteria;  
      long ix[1];  
      SAFEARRAY *pSa = NULL;  
  
      pCn->Provider = "sqloledb";  
      pCn->Open("Data Source='(local)';Initial Catalog='pubs';Integrated Security=SSPI", "", "", adConnectUnspecified);  
      // Note 2, Note 3  
      pSa = SafeArrayCreateVector(VT_VARIANT, 1, 4);  
      if (!pSa)   
         _com_issue_error(E_OUTOFMEMORY);  
  
      // Specify TABLE_NAME in the third array element (index of 2).   
      ix[0] = 2;        
      TESTHR(SafeArrayPutElement(pSa, ix, &vtTableName));  
  
      // There is no Variant constructor for a SafeArray, so manually set the   
      // type (SafeArray of Variant) and value (pointer to a SafeArray).  
  
      vtCriteria.vt = VT_ARRAY | VT_VARIANT;  
      vtCriteria.parray = pSa;  
  
      pRs = pCn->OpenSchema(adSchemaColumns, vtCriteria, vtMissing);  
  
      long limit = pRs->GetFields()->Count;  
      for ( long x = 0 ; x < limit ; x++ )  
         printf( "%d: %s\n", x + 1, ((char*) pRs->GetFields()->Item[x]->Name) );  
      // Note 4  
      pRs->Close();  
      pCn->Close();  
   }  
   catch (_com_error &e) {  
      printf("Error:\n");  
      printf("Code = %08lx\n", e.Error());  
      printf("Code meaning = %s\n", (char*) e.ErrorMessage());  
      printf("Source = %s\n", (char*) e.Source());  
      printf("Description = %s\n", (char*) e.Description());  
   }  
   CoUninitialize();  
}  

Utilisation de la propriété Get/Put/PutRef

Dans Visual Basic, le nom d’une propriété n’est pas qualifié selon qu’il soit récupéré, assigné ou référencé.

Public Sub GetPutPutRef  
Dim rs As New ADODB.Recordset  
Dim cn As New ADODB.Connection  
Dim sz as Integer  
cn.Open "Provider=sqloledb;Data Source=yourserver;" & _  
         "Initial Catalog=pubs;Integrated Security=SSPI;"  
rs.PageSize = 10  
sz = rs.PageSize  
rs.ActiveConnection = cn  
rs.Open "authors",,adOpenStatic  
' ...  
rs.Close  
cn.Close  
End Sub  

Cet exemple Visual C++ illustre l'Obtenir/Put/PutRefProperty.

Notes

Les notes suivantes correspondent aux sections commentées de l’exemple de code.

  1. Cet exemple utilise deux formes d’argument de chaîne manquant : une constante explicite, strMissing, et une chaîne que le compilateur utilisera pour créer un _bstr_t temporaire qui existera pour l’étendue de la méthode Open .

  2. Il n’est pas nécessaire de caster l’opérande de rs->PutRefActiveConnection(cn) pour (IDispatch *) car le type de l’opérande est déjà (IDispatch *).

// Visual_CPP_ado_prog_2.cpp  
// compile with: /EHsc  
#import "msado15.dll" no_namespace rename("EOF", "EndOfFile")  
  
int main() {  
   CoInitialize(NULL);  
   try {  
      _ConnectionPtr cn("ADODB.Connection");  
      _RecordsetPtr rs("ADODB.Recordset");  
      _bstr_t strMissing(L"");  
      long oldPgSz = 0, newPgSz = 5;  
  
      // Note 1  
      cn->Provider = "sqloledb";  
      cn->Open("Data Source='(local)';Initial Catalog=pubs;Integrated Security=SSPI;", strMissing, "", adConnectUnspecified);  
  
      oldPgSz = rs->GetPageSize();  
      // -or-  
      // oldPgSz = rs->PageSize;  
  
      rs->PutPageSize(newPgSz);  
      // -or-  
      // rs->PageSize = newPgSz;  
  
      // Note 2  
      rs->PutRefActiveConnection( cn );  
      rs->Open("authors", vtMissing, adOpenStatic, adLockReadOnly, adCmdTable);  
      printf("Original pagesize = %d, new pagesize = %d\n", oldPgSz, rs->GetPageSize());  
      rs->Close();  
      cn->Close();  
  
   }  
   catch (_com_error &e) {  
      printf("Description = %s\n", (char*) e.Description());  
   }  
   ::CoUninitialize();  
}  

Utilisation de GetItem(x) et Item[x]

Cet exemple Visual Basic illustre la syntaxe standard et alternative pour Item().

Public Sub GetItemItem  
Dim rs As New ADODB.Recordset  
Dim name as String  
rs = rs.Open "authors", "DSN=pubs;", adOpenDynamic, _  
         adLockBatchOptimistic, adTable  
name = rs(0)  
' -or-  
name = rs.Fields.Item(0)  
rs(0) = "Test"  
rs.UpdateBatch  
' Restore name  
rs(0) = name  
rs.UpdateBatch  
rs.Close  
End Sub  

Cet exemple Visual C++ illustre l'élément .

Note

La remarque suivante correspond aux sections commentées dans l’exemple de code : lorsque la collection est accessible avec Élément, l’index, 2, doit être converti en longue afin qu’un constructeur approprié soit appelé.

// Visual_CPP_ado_prog_3.cpp  
// compile with: /EHsc  
#import "msado15.dll" no_namespace rename("EOF", "EndOfFile")  
  
void main() {  
   CoInitialize(NULL);  
   try {  
      _ConnectionPtr cn("ADODB.Connection");  
      _RecordsetPtr rs("ADODB.Recordset");  
      _variant_t vtFirstName;  
  
      cn->Provider = "sqloledb";  
      cn->Open("Data Source='(local)';Initial Catalog=pubs;Integrated Security=SSPI;", "", "", adConnectUnspecified);  
  
      rs->PutRefActiveConnection( cn );  
      rs->Open("authors", vtMissing, adOpenStatic, adLockOptimistic, adCmdTable);  
      rs->MoveFirst();  
  
      // Note 1. Get a field.  
      vtFirstName = rs->Fields->GetItem((long)2)->GetValue();  
      // -or-  
      vtFirstName = rs->Fields->Item[(long)2]->Value;  
  
      printf( "First name = '%s'\n", (char*)( (_bstr_t)vtFirstName) );  
  
      rs->Fields->GetItem((long)2)->Value = L"TEST";  
      rs->Update(vtMissing, vtMissing);  
  
      // Restore name  
      rs->Fields->GetItem((long)2)->PutValue(vtFirstName);  
      // -or-  
      rs->Fields->GetItem((long)2)->Value = vtFirstName;  
      rs->Update(vtMissing, vtMissing);  
      rs->Close();  
   }  
   catch (_com_error &e) {  
      printf("Description = '%s'\n", (char*) e.Description());  
   }  
   ::CoUninitialize();  
}  

Conversion de pointeurs d'objet ADO en utilisant (IDispatch *)

L’exemple Visual C++ suivant illustre l’utilisation (IDispatch *) pour convertir des pointeurs d’objet ADO.

Notes

Les notes suivantes correspondent aux sections commentées de l’exemple de code.

  1. Spécifiez un objet Connection ouvert dans un variantcodé explicitement. Convertir avec (IDispatch *) afin que le constructeur correct soit appelé. En outre, définissez explicitement le deuxième paramètre _variant_t sur la valeur par défaut de true, afin que le nombre de références d’objets soit correct lorsque l’opération Recordset ::Open se termine.

  2. L’expression, (_bstr_t), n’est pas un cast, mais un opérateur _variant_t qui extrait une chaîne _bstr_t à partir de l'Variant retourné par Valeur.

L’expression, (char*), n’est pas un cast, mais un opérateur _bstr_t qui extrait un pointeur vers la chaîne encapsulée dans un objet _bstr_t.

Cette section de code illustre certains des comportements utiles des opérateurs _variant_t et _bstr_t.

// Visual_CPP_ado_prog_4.cpp  
// compile with: /EHsc  
#import "msado15.dll" no_namespace rename("EOF", "EndOfFile")  
  
int main() {  
   CoInitialize(NULL);  
   try {  
      _ConnectionPtr pConn("ADODB.Connection");  
      _RecordsetPtr pRst("ADODB.Recordset");  
  
      pConn->Provider = "sqloledb";  
      pConn->Open("Data Source='(local)';Initial Catalog='pubs';Integrated Security=SSPI", "", "", adConnectUnspecified);  
  
      // Note 1.  
      pRst->Open("authors", _variant_t((IDispatch *) pConn, true), adOpenStatic, adLockReadOnly, adCmdTable);  
      pRst->MoveLast();  
  
      // Note 2.  
      printf("Last name is '%s %s'\n",   
         (char*) ((_bstr_t) pRst->GetFields()->GetItem("au_fname")->GetValue()),  
         (char*) ((_bstr_t) pRst->Fields->Item["au_lname"]->Value));  
  
      pRst->Close();  
      pConn->Close();  
   }  
   catch (_com_error &e) {  
      printf("Description = '%s'\n", (char*) e.Description());  
   }     
   ::CoUninitialize();  
}