次の方法で共有


レコードセット: バルク行フェッチ (ODBC)

このトピックの内容は、MFC ODBC クラスに該当します。

CRecordset クラスは、バルク行フェッチをサポートしています。バルク行フェッチとは、データ ソースから一度に 1 つのレコードを取得するのではなく、複数のレコードを同時に取得することを指します。 バルク行フェッチを実装できるのは、CRecordset の派生クラスだけです。 データ ソースからレコードセット オブジェクトに複数行のデータを転送する方法は、バルク レコード フィールド エクスチェンジ (Bulk RFX: Bulk Record Field Exchange) と呼ばれます。 CRecordset の派生クラスでバルク行フェッチを使用しない場合は、データがレコード フィールド エクスチェンジ (RFX: Record Field Exchange) で転送されることに注意してください。 詳細については、「レコード フィールド エクスチェンジ (RFX)」を参照してください。

このトピックでは、次の内容について説明します。

  • CRecordset でバルク行フェッチをサポートする方法

  • バルク行フェッチを使用する場合の注意事項

  • バルク レコード フィールド エクスチェンジ (Bulk RFX: Bulk Record Field Exchange) の実装方法

CRecordset でバルク行フェッチをサポートする方法

レコードセット オブジェクトを開く前に、行セットのサイズを SetRowsetSize メンバー関数で定義できます。 行セットのサイズは、一度のフェッチで取得するレコード数を指します。 バルク行フェッチが実装されている場合、既定の行セットのサイズは 25 です。 バルク行フェッチが実装されていない場合、行セットのサイズは 1 に固定されたままです。

行セットのサイズを定義したら、Open メンバー関数を呼び出します。 バルク行フェッチを実装するには、ここで dwOptions パラメーターの CRecordset::useMultiRowFetch オプションを指定します。 ほかに、CRecordset::userAllocMultiRowBuffers オプションも指定できます。 バルク レコード フィールド エクスチェンジ機構では、フェッチで取得した複数行のデータを配列に格納します。 配列の格納バッファーは、フレームワークによって自動的に割り当てることも、手動で割り当てることもできます。 手動で割り当てるには、CRecordset::userAllocMultiRowBuffers を指定します。

次の表は、バルク行フェッチをサポートするために CRecordset が提供しているメンバー関数の一覧です。

メンバー関数

説明

CheckRowsetError

フェッチ中に発生したエラーを処理する仮想関数です。

DoBulkFieldExchange

バルク レコード フィールド エクスチェンジを実装します。 データ ソースからレコードセット オブジェクトに複数行のデータを転送するときに、自動的に呼び出されます。

GetRowsetSize

行セットのサイズの現在の設定を取得します。

GetRowsFetched

フェッチで実際に取得された行数を示します。 行セットのフェッチが不完全であった場合を除いて、行セットのサイズと同じになります。

GetRowStatus

行セット内の特定の行に関するフェッチ ステータスを返します。

RefreshRowset

行セット内の特定の行のデータとステータスを更新します。

SetRowsetCursorPosition

行セット内の特定の行にカーソルを移動します。

SetRowsetSize

行セットのサイズの設定を指定された値に変更する仮想関数です。

バルク行フェッチを使用する場合の注意事項

バルク行フェッチを使用すると、パフォーマンスの向上につながる反面、一部の機能が変更されます。 バルク行フェッチを実装する前に、以下の事項を確認しておいてください。

  • フレームワークでは、DoBulkFieldExchange メンバー関数が自動的に呼び出され、データがデータ ソースからレコードセット オブジェクトに転送されます。 しかし、レコードセットからデータ ソースには転送されません。 AddNewEditDelete、または Update の各メンバー関数を呼び出すと、アサーションは失敗します。 CRecordset には、現在複数行のデータを更新する機構はありませんが、ODBC API 関数の SQLSetPos を使用すると、独自の関数を記述できます。 SQLSetPos の詳細については、MSDN ドキュメントの『ODBC SDK Programmer's Reference』を参照してください。

  • IsDeletedIsFieldDirtyIsFieldNullIsFieldNullableSetFieldDirty、および SetFieldNull の各メンバー関数は、バルク行フェッチを実装しているレコードセットでは使用できません。 ただし、IsDeleted の代わりに GetRowStatus を、IsFieldNullable の代わりに GetODBCFieldInfo を呼び出すことができます。

  • Move を呼び出すと、レコードセットは行セット単位で移動します。 たとえば、レコードセットに 100 のレコードがあり、このレコードセットの最初の行セット サイズが 10 であるとします。 Open を呼び出すと、1 から 10 までの行がフェッチされ、現在のレコードは行 1 になります。 ここで MoveNext を呼び出すと、次の行ではなくて次の行セットがフェッチされます。 この行セットは 11 から 20 までの行で構成され、現在のレコードは行 11 になります。 バルク行フェッチが実装されている場合、MoveNextMove( 1 ) は等しくないことに注意してください。 Move(1) は、現在のレコードに続く次の行からフェッチします。 この例の場合、Open を呼び出した後に Move( 1 ) を呼び出すと、行 2 から行 11 までの行で構成される行セットがフェッチされ、現在のレコードは行 2 になります。 詳細については、Move メンバー関数に関するトピックを参照してください。

  • ウィザードは、レコード フィールド エクスチェンジをサポートしていますが、バルク レコード フィールド エクスチェンジをサポートしていません。 つまり、フィールド データ メンバーを手動で宣言したり、Bulk RFX 関数の呼び出しを記述して DoBulkFieldExchange を手動でオーバーライドしたりする必要があります。 詳細については、『MFC リファレンス』の「レコード フィールド エクスチェンジ (RFX) 関数」を参照してください。

バルク レコード フィールド エクスチェンジ (Bulk RFX: Bulk Record Field Exchange) の実装方法

バルク レコード フィールド エクスチェンジは、データ ソースからレコードセット オブジェクトにデータの行セットを転送します。 Bulk RFX 関数は、転送された行セットを配列に格納し、行セット内の各データ項目の長さも配列に格納します。 データの配列にアクセスするには、クラス定義でフィールド データ メンバーをポインターとして定義します。 さらに、長さの配列にアクセスするためのポインターも定義します。 パラメーター データ メンバーは、ポインターとして宣言しません。バルク レコード フィールド エクスチェンジでのパラメーター データ メンバーの宣言方法は、レコード フィールド エクスチェンジの場合と同じです。 次に簡単なコードの例を示します。

class MultiRowSet : public CRecordset
{
public:
   // Field/Param Data
      // field data members
      long* m_rgID;
      LPSTR m_rgName;

      // pointers for the lengths
      // of the field data
      long* m_rgIDLengths;
      long* m_rgNameLengths;

      // input parameter data member
      CString m_strNameParam;

   .
   .
   .
}

配列の格納バッファーは、フレームワークによって自動的に割り当てることも、手動で割り当てることもできます。 手動で割り当てるには、Open メンバー関数で dwOptions パラメーターの CRecordset::userAllocMultiRowBuffers オプションを指定します。 配列のサイズは、行セットのサイズ以上とします。 フレームワークによって自動的に配列を割り当てるには、ポインターを NULL に初期化します。 通常、この初期化は、レコードセット オブジェクトのコンストラクターで行います。

MultiRowSet::MultiRowSet( CDatabase* pDB )
   : CRecordset( pDB )
{
   m_rgID = NULL;
   m_rgName = NULL;
   m_rgIDLengths = NULL;
   m_rgNameLengths = NULL;
   m_strNameParam = "";

   m_nFields = 2;
   m_nParams = 1;

   .
   .
   .
}

最後に、DoBulkFieldExchange メンバー関数をオーバーライドします。 フィールド データ メンバーに対しては Bulk RFX 関数を呼び出し、パラメーター データ メンバーに対しては RFX 関数を呼び出します。 SQL ステートメントまたはストアド プロシージャを Open に渡してレコードセットを開いた場合は、レコードセットの列の順序に従って Bulk RFX 関数を呼び出します。同じように、パラメーターに対する RFX 関数は、SQL ステートメントまたはストアド プロシージャのパラメーターの順序に従って呼び出します。

void MultiRowSet::DoBulkFieldExchange( CFieldExchange* pFX )
{
   // call the Bulk RFX functions
   // for field data members
   pFX->SetFieldType( CFieldExchange::outputColumn );
   RFX_Long_Bulk( pFX, _T( "[colRecID]" ),
                  &m_rgID, &m_rgIDLengths );
   RFX_Text_Bulk( pFX, _T( "[colName]" ),
                  &m_rgName, &m_rgNameLengths, 30 );


   // call the RFX functions for
   // for parameter data members
   pFX->SetFieldType( CFieldExchange::inputParam );
   RFX_Text( pFX, "NameParam", m_strNameParam );
}

注意

CRecordset の派生クラスがスコープの外に出る前に、Close メンバー関数を必ず呼び出してください。 これは、フレームワークによって割り当てられたメモリを解放するためです。 バルク行フェッチを実装しているかどうかにかかわらず、プログラミング上の習慣として、常に Close を明示的に呼び出すことをお勧めします。

レコード フィールド エクスチェンジ (RFX: Record Field Exchange) の詳細については、「レコード フィールド エクスチェンジ : RFX の動作のしくみ」を参照してください。 パラメーターの使い方の詳細については、「CFieldExchange::SetFieldType」と「レコードセット : パラメーターを利用したレコードセット (ODBC)」を参照してください。

参照

参照

CRecordset::m_nFields

CRecordset::m_nParams

概念

レコードセット (ODBC)