次の方法で共有


Visual C++ ADO プログラミング

ADO API リファレンスでは、Microsoft Visual Basic のような構文を使用した ADO アプリケーション プログラミング インターフェイス (API) の機能について説明します。 対象ユーザーは全員ですが、ADO プログラマは Visual Basic、Visual C++ ( #import ディレクティブあり/なし)、Visual J++ (ADO/WFC クラス パッケージあり) などの多様な言語を使用します。

Microsoft は 2004 年に Visual J++ のサポートを終了しました。

この多様性に対応するために、 ADO for Visual C++ 構文インデックス は、API リファレンスの機能、パラメーター、例外的な動作などの一般的な説明へのリンクを含む Visual C++ 言語固有の構文を提供します。

ADO は COM (コンポーネント オブジェクト モデル) インターフェイスと共に実装されます。 ただし、プログラマは、他のプログラミング言語よりも特定のプログラミング言語で COM を操作する方が簡単です。 たとえば、COM の使用に関するほぼすべての詳細は Visual Basic プログラマに対して自動的に処理されますが、Visual C++ プログラマはそれらの詳細を自分で処理する必要があります。

以降のセクションでは、ADO と #import ディレクティブを使用する C および C++ プログラマの詳細をまとめます。 COM (バリアント型、 BSTR 型、 SafeArray 型) に固有のデータ型とエラー処理 (_com_error) に重点を置いています。

#import コンパイラ ディレクティブの使用

#import Visual C++ コンパイラ ディレクティブは、ADO のメソッドとプロパティの操作を簡略化します。 このディレクティブは、ADO .dll (Msado15.dll) などのタイプ ライブラリを含むファイルの名前を受け取り、typedef 宣言、インターフェイスのスマート ポインター、列挙定数を含むヘッダー ファイルを生成します。 各インターフェイスは、クラスにカプセル化またはラップされます。

クラス内の各操作 (つまり、メソッドまたはプロパティの呼び出し) には、操作を直接呼び出す宣言 (つまり、"生" 形式の操作) と、未加工の操作を呼び出して、操作が正常に実行できなかった場合に COM エラーをスローする宣言があります。 操作がプロパティの場合は、通常、Visual Basic などの構文を持つ操作の代替構文を作成するコンパイラ ディレクティブがあります。

プロパティの値を取得する操作には、フォームの名前 である GetProperty があります。 プロパティの値を設定する操作には、フォームの名前 Putプロパティがあります。 ADO オブジェクトへのポインターを持つプロパティの値を設定する操作には、フォームの名前 PutRefプロパティがあります。

次のフォームの呼び出しでプロパティを取得または設定できます。

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

プロパティ ディレクティブの使用

__declspec(property...) コンパイラ ディレクティブは、代替構文を持つプロパティとして使用される関数を宣言する Microsoft 固有の C 言語拡張機能です。 その結果、Visual Basic と同様の方法でプロパティの値を設定または取得できます。 たとえば、次の方法でプロパティを設定および取得できます。

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

コーディングする必要がないことに注意してください。

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

コンパイラは、宣言されている代替構文と、プロパティが読み取られるか書き込まれているかに基づいて、適切な Get-、Put-、または PutRefプロパティの呼び出しを生成します。

__declspec(property...) コンパイラ ディレクティブは、関数の getput、または getの代替構文のみを宣言できます。 読み取り専用操作には get 宣言しかありません。書き込み専用の操作には put 宣言しかありません。読み取りと書き込みの両方の操作には、 get 宣言と put 宣言の両方があります。

このディレクティブでは、2 つの宣言のみが可能です。ただし、各プロパティには、 GetPropertyPutPropertyおよび PutRefプロパティの 3 つのプロパティ関数があります。 その場合、代替構文を持つのは、プロパティの 2 つの形式のみです。

たとえば、 Command オブジェクト ActiveConnection プロパティは、 GetActiveConnectionPutRefActiveConnection の代替構文で宣言されます。 実際には、このプロパティに開いている Connection オブジェクト (つまり、Connection オブジェクト ポインター) を配置する必要があるため、PutRef- 構文を使用することをお勧めします。 一方、 Recordset オブジェクトには GetPut-、 PutRefActiveConnection の操作がありますが、代替構文はありません。

コレクション、GetItem メソッド、および Item プロパティ

ADO では、 フィールドパラメータープロパティエラーなど、いくつかのコレクションを定義します。 Visual C++ では、 GetItem(index) メソッドはコレクションのメンバーを返します。 Indexバリアント型 (コレクション内のメンバーの数値インデックス、またはメンバーの名前を含む文字列) の値です。

__declspec(property...) コンパイラ ディレクティブは、各コレクションの基本的な GetItem() メソッドの代替構文として Item プロパティを宣言します。 別の構文では角かっこが使用され、配列参照に似ています。 一般に、2 つの形式は次のようになります。

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

たとえば、pubs データベースの authors テーブルから派生した rs という名前の Recordset オブジェクトのフィールドに値を割り当てます。 Recordset オブジェクト Fieldsコレクションの 3 番目の Field にアクセスするには、Item() プロパティを使用します (コレクションは 0 からインデックスが付けられます。3 番目のフィールドの名前は au_fname であると仮定します)。 次に、Field オブジェクトの Value() メソッドを呼び出して、文字列値を割り当てます。

これは、次の 4 つの方法で Visual Basic で表すことができます (最後の 2 つのフォームは Visual Basic に固有です。他の言語には同等のものはありません)。

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

Visual C++ では、上記の最初の 2 つの形式と同等の形式を次に示します。

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

または ( Value プロパティの代替構文も示されています)

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

コレクションの反復処理の例については、「ADO リファレンス」の「ADO コレクション」セクションを参照してください。

COM-Specific データ型

一般に、ADO API リファレンスで見つかる Visual Basic データ型には、Visual C++ と同等のものがあります。 これには、Visual Basic Byte の場合は unsigned charInteger の場合は shortLong の場合は long などの標準データ型が含まれます。 構文 Indexesto を見て、特定のメソッドまたはプロパティのオペランドに必要な内容を正確に確認します。

この規則の例外は、COM に固有のデータ型です。 バリアント型、 BSTR 型、 SafeArray 型です。

変種

バリアント型は、値メンバーとデータ型メンバーを含む構造化データ型です。 Variant には、別の Variant、BSTR、Boolean、IDispatch、IUnknown ポインター、通貨、日付など、さまざまなデータ型が含まれている場合があります。 COM には、あるデータ型を別のデータ型に簡単に変換できるメソッドも用意されています。

_variant_t クラスは、Variant データ型をカプセル化して管理します。

ADO API Reference でメソッドまたはプロパティオペランドが値を受け取ると言う場合、通常は値が_variant_tで渡されたことを意味 します

この規則は、ADO API リファレンスのトピックの Parameters セクションでオペランドが バリアント型である場合に明示的に当てはまります。 1 つの例外は、オペランドが LongByte などの標準データ型、または列挙型を受け取るとドキュメントで明示的に示されている場合です。 もう 1 つの例外は、オペランドが 文字列を受け取る場合です。

BSTR

BSTR (Basic STRing) は、文字列と文字列の長さを含む構造化データ型です。 COM には、 BSTR の割り当て、操作、解放を行うメソッドが用意されています。

_bstr_t クラスは、BSTR データ型をカプセル化して管理します。

ADO API リファレンスで、メソッドまたはプロパティが 文字列 値を受け取ると、値が _bstr_tの形式であることを意味します。

_variant_tクラスと_bstr_t クラスのキャスト

多くの場合、 _variant_tを明示的 にコーディングしたり、操作の引数に _bstr_t したりする必要はありません。 _variant_tクラスまたは_bstr_t クラスに引数のデータ型と一致するコンストラクターがある場合、コンパイラは適切な_variant_tまたは_bstr_tを生成します。

ただし、引数があいまいな場合、つまり、引数のデータ型が複数のコンストラクターと一致する場合は、適切なデータ型で引数をキャストして、正しいコンストラクターを呼び出す必要があります。

たとえば、 Recordset::Open メソッドの宣言は次のとおりです。

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

ActiveConnection引数は_variant_tへの参照を受け取ります。接続文字列または開いている Connection オブジェクトへのポインターとしてコーディングできます。

"DSN=pubs;uid=MyUserName;pwd=<password>;" などの文字列または "(IDispatch *) pConn" などのポインターを渡すと、正しい_variant_tが暗黙的に構築されます。

Windows 認証をサポートするデータ ソース プロバイダーに接続する場合は、接続文字列のユーザー ID とパスワード情報の代わりに、Trusted_Connection=yes または Integrated Security = SSPI を指定する必要があります。

または、"_variant_t((IDispatch *) pConn, true)" などのポインターを含む_variant_tを明示的にコーディングすることもできます。 キャスト(IDispatch *)は、IUnknown インターフェイスへのポインターを受け取る別のコンストラクターを用いてあいまいさを解決します。

ADO が IDispatch インターフェイスであることは、ほとんど言及しませんが、非常に重要です。 ADO オブジェクトへのポインターを Variant として渡す必要がある場合は常に、そのポインターを IDispatch インターフェイスへのポインターとしてキャストする必要があります。

最後のケースでは、コンストラクターの 2 番目のブール値引数を、省略可能な既定値の true で明示的にコード化します。 この引数を指定すると 、Variant コンストラクターは AddRef() メソッドを呼び出します。このメソッドは、ADO メソッドまたはプロパティ呼び出しが完了したときに 、_variant_t::Release() メソッドを自動的に呼び出す ADO を補正します。

SafeArray

SafeArray は、他のデータ型の配列を含む構造化データ型です。 SafeArray は、各配列次元の境界に関する情報を含み、それらの境界内の配列要素へのアクセスを制限するため、安全と呼ばれます。

ADO API Reference がメソッドまたはプロパティが配列を受け取るか返すと、メソッドまたはプロパティがネイティブの C/C++ 配列ではなく SafeArray を受け取るか返すかを意味します。

たとえば、 Connection オブジェクト OpenSchema メソッドの 2 番目のパラメーターには、 Variant 値の配列が必要です。 これらの バリアント型 の値は SafeArray の要素として渡す必要があり、 SafeArray は別の Variant の値として設定する必要があります。 OpenSchema の 2 番目の引数として渡されるその他のバリアントです。

さらに例として、Find メソッドの最初の引数は、値が 1 次元の SafeArray である Variant です。AddNew の省略可能な 1 番目と 2 番目の引数はそれぞれ 1 次元の SafeArray ですGetRows メソッドの戻り値は、値が 2 次元 SafeArray である Variant です。

不足しているパラメーターと既定のパラメーター

Visual Basic では、メソッドにパラメーターがない場合があります。 たとえば、 Recordset オブジェクト Open メソッドには 5 つのパラメーターがありますが、中間パラメーターをスキップして、末尾のパラメーターを省略できます。 既定の BSTR または バリアント 型は、不足しているオペランドのデータ型に応じて置き換えられます。

C/C++ では、すべてのオペランドを指定する必要があります。 データ型が文字列である不足しているパラメーターを指定する場合は、null 文字列を含む _bstr_t を指定します。 データ型が Variant である不足しているパラメーターを指定する場合は、DISP_E_PARAMNOTFOUNDの値と VT_ERROR の型を持つ_variant_tを指定します。 または、 同等の_variant_t 定数 vtMissing を指定します。 これは、#import ディレクティブによって提供されます。

3 つのメソッドは、 vtMissing の一般的な使用の例外です。 これらは、Connection オブジェクトと Command オブジェクトの Execute メソッドと、Recordset オブジェクトの NextRecordset メソッドです。 署名は次のとおりです。

_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  

RecordsAffectedParameters は、Variant 型へのポインターです。 Parameters は、実行されるコマンドを変更する 1 つのパラメーターまたはパラメーターの配列を含む Variant のアドレスを指定する入力パラメーターです。 RecordsAffected は、 バリアント型 (Variant) のアドレスを指定する出力パラメーターで、メソッドの影響を受ける行数が返されます。

Command オブジェクト Execute メソッドで、パラメーター&vtMissing (推奨) または null ポインター (つまり NULL またはゼロ (0)) に設定してパラメーターが指定されていないことを示します。 Parameters が null ポインターに設定されている場合、メソッドは内部的に同等の vtMissing に置き換えてから、操作を完了します。

すべてのメソッドで、 RecordsAffected を null ポインターに設定して、影響を受けるレコードの数を返さないことを示します。 この場合、null ポインターは欠損しているパラメーターというよりも、メソッドが影響を受けたレコード数を無視するべきであることを示す指標です。

したがって、これら 3 つのメソッドでは、次のようなコードを記述することが有効です。

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

エラー処理

COM では、ほとんどの操作は、関数が正常に完了したかどうかを示す HRESULT リターン コードを返します。 #import ディレクティブは、各 "raw" メソッドまたはプロパティのラッパー コードを生成し、返された HRESULT をチェックします。 HRESULT がエラーを示す場合、ラッパー コードは HRESULT リターン コードを引数として _com_issue_errorex() を呼び出すことによって COM エラーをスローします。 COM エラー オブジェクトは、 try-catch ブロックでキャッチできます。 (効率を高めるために、 _com_error オブジェクトへの参照をキャッチします)。

これらは ADO エラーです。ADO 操作が失敗した結果です。 基になるプロバイダーによって返されるエラーは、Connectionオブジェクト Errors コレクションの Error オブジェクトとして表示されます。

#import ディレクティブは、ADO .dllで宣言されたメソッドとプロパティのエラー処理ルーチンのみを作成します。 ただし、独自のエラー チェック マクロまたはインライン関数を記述することで、この同じエラー処理メカニズムを利用できます。 例については、 トピック、Visual C++ 拡張機能、または次のセクションのコードを参照してください。

Visual C++ の Visual Basic 規則に相当するもの

Visual Basic でコード化された ADO ドキュメントのいくつかの規則と、Visual C++ での同等の規則の概要を次に示します。

ADO オブジェクトの宣言

Visual Basic では、ADO オブジェクト変数 (この場合は Recordset オブジェクトの場合) は次のように宣言されます。

Dim rst As ADODB.Recordset  

句 "ADODB.Recordset" は、レジストリで定義されている Recordset オブジェクトの ProgID です。 Record オブジェクトの新しいインスタンスは、次のように宣言されます。

Dim rst As New ADODB.Recordset  

-又は-

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

Visual C++ では、 #import ディレクティブは、すべての ADO オブジェクトに対してスマート ポインター型宣言を生成します。 たとえば、 _Recordset オブジェクトを指す変数は _RecordsetPtr型であり、次のように宣言されます。

_RecordsetPtr  rs;  

_Recordset オブジェクトの新しいインスタンスを指す変数は、次のように宣言されます。

_RecordsetPtr  rs("ADODB.Recordset");  

-又は-

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

-又は-

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

CreateInstance メソッドを呼び出した後、変数は次のように使用できます。

rs->Open(...);  

あるケースでは、変数がクラス (rs.CreateInstance) のインスタンスであるかのように "." 演算子が使用され、別のケースでは、変数がインターフェイス (rs->Open) へのポインターであるかのように "->" 演算子が使用されます。

1 つの変数は、"->" 演算子がオーバーロードされ、クラスのインスタンスがインターフェイスへのポインターのように動作できるようにするために、2 つの方法で使用できます。 インスタンス変数のプライベート クラス メンバーには、 _Recordset インターフェイスへのポインターが含まれています。"->" 演算子はそのポインターを返し、返されたポインターは_Recordset オブジェクトのメンバー アクセスします。

不足しているパラメーターのコーディング - 文字列

Visual Basic で不足している 文字列 オペランドをコーディングする必要がある場合は、オペランドを省略するだけです。 Visual C++ でオペランドを指定する必要があります。 空の文字列を値として持つ _bstr_t をコーディングします。

_bstr_t strMissing(L"");  

不足しているパラメーターのコーディング - バリアント型 (Variant)

Visual Basic で不足している Variant オペランドをコーディングする必要がある場合は、オペランドを省略するだけです。 Visual C++ では、すべてのオペランドを指定する必要があります。 Variantパラメーターが欠落している場合、_variant_tを特別な値 DISP_E_PARAMNOTFOUND に設定し、型をVT_ERRORとしてコード化します。 または、 vtMissing を指定します。これは、 #import ディレクティブによって提供される同等の定義済み定数です。

_variant_t  vtMissingYours(DISP_E_PARAMNOTFOUND, VT_ERROR);   

-または使用-

...vtMissing...;  

バリアント型 (Variant) の宣言

Visual Basic では、 バリアント 型は 次のように Dim ステートメントで宣言されます。

Dim VariableName As Variant  

Visual C++ で、変数を型 _variant_tとして宣言します。 いくつかの概略 _variant_t 宣言を次に示します。

これらの宣言は、独自のプログラムで何をコーディングするかについての大まかなアイデアを与えるだけです。 詳細については、以下の例と 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);  

バリアントの配列の使用

Visual Basic では、次のコード例に示すように、 バリアント 型の配列を Dim ステートメントでコーディングすることも、 Array 関数を使用することもできます。

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  

次の Visual C++ の例では、_variant_tで使用される SafeArray の使用を示します。

注記

次のノートは、コード例のコメント付きセクションに対応しています。

  1. もう一度、TESTHR() インライン関数は、既存のエラー処理メカニズムを利用するように定義されています。

  2. 1 次元配列のみが必要なので、汎用の SAFEARRAYBOUND 宣言と SafeArrayCreate 関数の代わりに SafeArrayCreateVector を使用できます。 SafeArrayCreate を使用したコードの外観を次に示します。

       SAFEARRAYBOUND   sabound[1];  
       sabound[0].lLbound = 0;  
       sabound[0].cElements = 4;  
       pSa = SafeArrayCreate(VT_VARIANT, 1, sabound);  
    
  3. 列挙定数 adSchemaColumns によって識別されるスキーマは、TABLE_CATALOG、TABLE_SCHEMA、TABLE_NAME、およびCOLUMN_NAMEの 4 つの制約列に関連付けられています。 したがって、4 つの要素を持つ Variant 値の配列が作成されます。 次に、3 番目の列 (TABLE_NAME) に対応する制約値が指定されます。

    返される Recordset は複数の列で構成され、そのサブセットは制約列です。 返される各行の制約列の値は、対応する制約値と同じである必要があります。

  4. SafeArrays に精通しているユーザーは、SafeArrayDestroy() が終了前に呼び出されないことに驚くかもしれません。 実際、この場合 に SafeArrayDestroy() を呼び出すと、実行時例外が発生します。 その理由は、vtCriteriaのデストラクターは、_variant_tがスコープ外になると VariantClear() を呼び出し、SafeArray を解放するということです。 _variant_tを手動でクリアせずに SafeArrayDestroy を呼び出すと、デストラクターは無効な SafeArray ポインターをクリアしようとします。

    SafeArrayDestroy が呼び出された場合、コードは次のようになります。

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

    ただし、 _variant_tSafeArray を管理できるようにする方がはるかに簡単です。

// 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();  
}  

プロパティ Get/Put/PutRef の使用

Visual Basic では、プロパティの名前は、取得、割り当て、または参照の割り当てによって修飾されません。

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  

この Visual C++ の例では、 Get/Put/PutRefプロパティを示します。

注記

次のノートは、コード例のコメント付きセクションに対応しています。

  1. この例では、不足している文字列引数の 2 つの形式を使用します。明示的な定数、strMissing、およびコンパイラが Open メソッドのスコープに存在する一時的な_bstr_tを作成するために使用する文字列です。

  2. オペランドの型は既に(IDispatch *)されているため、rs->PutRefActiveConnection(cn)のオペランドを(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();  
}  

GetItem(x) と Item[x] の使用

この Visual Basic の例では、 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  

この Visual C++ の例では 、Item を示します。

次のメモは、コード例のコメント付きセクションに対応しています。 コレクションに Item でアクセスする場合、適切なコンストラクターが呼び出されるように、インデックス 2long にキャストする必要があります。

// 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();  
}  

(IDispatch *) を使用した ADO オブジェクト ポインターのキャスト

次の Visual C++ の例では、(IDispatch *) を使用して ADO オブジェクト ポインターをキャストする方法を示します。

注記

次のノートは、コード例のコメント付きセクションに対応しています。

  1. 明示的にコード化されたバリアント型 (Variant) で開いている Connection オブジェクトを指定します。 正しいコンストラクターが呼び出されるように、それを (IDispatch *) でキャストします。 また、2 番目 の _variant_t パラメーターを既定値 の true に明示的に設定すると、 Recordset::Open 操作が終了したときにオブジェクト参照数が正しくなります。

  2. (_bstr_t)はキャストではなく、Value によって返される Variant から_bstr_t文字列を抽出する_variant_t演算子です

(char*)はキャストではなく、 _bstr_t オブジェクト内のカプセル化された文字列へのポインターを抽出する _bstr_t 演算子です。

コードのこのセクションでは、_variant_t演算子と_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();  
}