動的アクセサーの使用
動的アクセサーを使うと、データベース スキーマ (基になる構造) がわからなくてもデータ ソースにアクセスできます。 OLE DB テンプレート ライブラリには、支援するクラスがいくつか用意されています。
DynamicConsumer サンプルを見ると、動的アクセサー クラスを使って、列情報を取得し、アクセサーを動的に作成する方法がわかります。
CDynamicAccessor の使用
CDynamicAccessor を使うと、データベース スキーマ (データベースの基になる構造) を知っていなくてもデータ ソースにアクセスできます。 CDynamicAccessor
メソッドは、列名、カウント、データ型などの列情報を取得します。 この列情報を使って、実行時にアクセサーを動的に作成します。 列情報は、このクラスによって作成および管理されるバッファーに格納されます。 GetValue メソッドを使って、バッファーからデータを取得します。
例: CDynamic アクセサー
// Using_Dynamic_Accessors.cpp
// compile with: /c /EHsc
#include <stdio.h>
#include <objbase.h>
#include <atldbcli.h>
int main(int argc, char* argv[] )
{
HRESULT hr = CoInitialize(NULL );
CDataSource ds;
CSession ss;
CTable<CDynamicAccessor> rs;
// The following is an example initialization string:
hr = ds.OpenFromInitializationString(L"Provider=SQLOLEDB.1;"
L"Integrated Security=SSPI;Persist Security Info=False;"
L"Initial Catalog=Loginname;Data Source=your_data_source;"
L"Use Procedure for Prepare=1;Auto Translate=True;"
L"Packet Size=4096;Workstation ID=LOGINNAME01;"
L"Use Encryption for Data=False;"
L"Tag with column collation when possible=False");
hr = ss.Open(ds );
hr = rs.Open(ss, "Shippers" );
hr = rs.MoveFirst();
while(SUCCEEDED(hr ) && hr != DB_S_ENDOFROWSET )
{
for(size_t i = 1; i <= rs.GetColumnCount(); i++ )
{
DBTYPE type;
rs.GetColumnType(i, &type );
printf_s( "Column %d [%S] is of type %d\n",
i, rs.GetColumnName(i ), type );
switch(type )
{
case DBTYPE_WSTR:
printf_s( "value is %S\n",
(WCHAR*)rs.GetValue(i ) );
break;
case DBTYPE_STR:
printf_s( "value is %s\n",
(CHAR*)rs.GetValue(i ) );
default:
printf_s( "value is %d\n",
*(long*)rs.GetValue(i ) );
}
}
hr = rs.MoveNext();
}
rs.Close();
ss.Close();
ds.Close();
CoUninitialize();
return 0;
}
CDynamicStringAccessor の使用
CDynamicStringAccessor は、1 つの重要な方法を除いて、CDynamicAccessor と同じように機能します。 CDynamicAccessor
はプロバイダーによって報告されるネイティブ形式でデータを要求するのに対し、CDynamicStringAccessor
は、データ ストアからアクセスされるすべてのデータを文字列データとしてフェッチするようプロバイダーに要求します。 このプロセスは、データ ストアの内容の表示や印刷など、データ ストアの値を計算する必要がない単純なタスクに特に便利です。
列の情報を取得するには、CDynamicStringAccessor
メソッドを使います。 この列情報を使って、実行時にアクセサーを動的に作成します。 列情報は、このクラスによって作成および管理されるバッファーに格納されます。 バッファーからデータを取得するには CDynamicStringAccessor::GetString を使い、バッファーにデータを格納するには CDynamicStringAccessor::SetString を使います。
例: CDynamicStringAccessor
// Using_Dynamic_Accessors_b.cpp
// compile with: /c /EHsc
#include <stdio.h>
#include <objbase.h>
#include <atldbcli.h>
int main(int argc, char* argv[] )
{
HRESULT hr = CoInitialize(NULL );
if (hr != S_OK)
{
exit (-1);
}
CDataSource ds;
CSession ss;
CTable<CDynamicStringAccessor> rs;
// The following is an example initialization string:
hr = ds.OpenFromInitializationString(L"Provider=SQLOLEDB.1;"
L"Integrated Security=SSPI;Persist Security Info=False;"
L"Initial Catalog=Loginname;Data Source=your_data_source;"
L"Use Procedure for Prepare=1;Auto Translate=True;"
L"Packet Size=4096;Workstation ID=LOGINNAME01;"
L"Use Encryption for Data=False;"
L"Tag with column collation when possible=False");
hr = ss.Open(ds );
hr = rs.Open(ss, "Shippers" );
hr = rs.MoveFirst();
while(SUCCEEDED(hr ) && hr != DB_S_ENDOFROWSET )
{
for(size_t i = 1; i <= rs.GetColumnCount(); i++ )
{
printf_s( "column %d value is %s\n",
i, rs.GetString(i ) );
}
hr = rs.MoveNext();
}
rs.Close();
ss.Close();
ds.Close();
CoUninitialize();
return 0;
}
CDynamicParameterAccessor の使用
CDynamicParameterAccessor は CDynamicAccessor と似ていますが、CDynamicParameterAccessor
は ICommandWithParameters インターフェイスを呼び出すことによって設定されるパラメーター情報を取得する点が異なります。 コンシューマーがこのクラスを使用するには、プロバイダーで ICommandWithParameters
がサポートされている必要があります。
パラメーター情報は、このクラスによって作成および管理されるバッファーに格納されます。 バッファーからパラメーター データを取得するには、CDynamicParameterAccessor::GetParam と CDynamicParameterAccessor::GetParamType を使います。
このクラスを使用して SQL Server ストアド プロシージャを実行し、出力パラメーター値を取得する方法を示す例については、GitHub の Microsoft VCSamples リポジトリにある DynamicConsumer のサンプル コードを参照してください。
関連項目
アクセサーの使用
CDynamicAccessor クラス
CDynamicStringAccessor クラス
CDynamicParameterAccessor クラス
DynamicConsumer サンプル