行の取得(FireDAC)

提供: Appmethod Topics
移動先: 案内検索

コマンドの操作(FireDAC) への移動

カーソルの処理

SQL コマンドが実行され、その結果行が返される必要がある場合、DBMS では DBMS サーバー上にカーソルを作成します。アプリケーションでは、カーソルを使用してデータベースから行を取得します。DBMS によっては、いくつかの種類のカーソルがある場合があります。カーソルの種類を選択するには、FetchOptions.CursorKind プロパティを使用します。デフォルトでは、最速の種類のカーソル(ckAutomatic)が選ばれています。まず第一に、このプロパティは Microsoft SQL Server にとって意味があります。

DBMS カーソルは、それ自身が開かれたトランザクション コンテキストに左右されます。詳細については、「トランザクションの管理」を参照してください。

行セット取得

行セット取得では、1 回のネットワーク ラウンドトリップでサーバーから取得されるレコードの数を指定できます。RowsetSize オプションを指定することで、実行する SELECT 文ごとに個別にこれを最適化して、ネットワーク ラウンドトリップの回数を最小限に抑えることができます。

行セットのサイズは FetchOptions.RowsetSize プロパティで制御されます。この数が大きければ大きいほど、結果セット全部が速く取得されますが、次の行セットを取得するまでの遅延も大きくなります。また、最初から "大きい" 値にすると、パフォーマンスが落ち始めます。実質的に、"大きい" 値とは 2000 ~ 3000 程度です。

メモ: 必ずしもすべての DBMS で行セット取得がサポートされているわけではありません。ただし、FireDAC では、速度を犠牲にしてこの機能をエミュレートできます。エミュレートされた行セット取得は、実際の取得に比べて速度が 50% 低下します。

FireDAC では、FetchOptions.Mode プロパティに従って、以下のように行セットを取得します。

  • fmOnDemand -- 直近に取得されたレコードより先へデータセットの現在位置が移動しようとすると、行セットが自動的に取得されます。
  • fmAll -- SQL コマンドの実行直後に、すべての行セットが自動的に取得されます。これは、FetchAll メソッドを呼び出す場合と似ています。
  • fmManual -- プログラムで FetchNext メソッドまたは FetchAll メソッドを使って手動で行セットを取得します。
  • fmExactRecsMax -- SQL コマンドの実行直後に、すべての行セットが自動的に取得されます。行数が FetchOptions.RecsMax と異なる場合は、例外が発生します。

FetchOptions.UnidirectionalTrue の場合は、次の行セットを取得する前に、前の行セットがメモリから破棄されます。これにより、大量の結果セットを取得する際に、PC のメモリを節約することができます。

すべてのレコードが取得されると、TFDDataSet.SourceEOFTrue に設定され、FetchOptions.AutoClose に基づいて元のコマンドが閉じられます。ただし、データセットそのものは閉じられません。

メモ: 詳細については、「コマンド バッチ」を参照してください。

アプリケーションでは、TFDDataSet.AfterGetRecord イベント ハンドラを使って、取得した各レコードにアクセスできます。

行ページング

FetchOptions.RecsSkipRecsMax により、結果セットのページングが可能になります。カーソルが開かれた後、最初の RecsSkip 個のレコードがスキップされます。残りのレコードのうち RecxMax 個までが取得されます。SQL 文が準備されている場合は、RecsSkip および RecsMax プロパティ値を変更しても、効果はありません。そのため、次の行ページを取得する前にコマンドをいったん準備解除し、その後で再度実行する必要があります。以下に例を示します。

 FDQuery1.FetchOptions.RecsSkip := 0;
 FDQuery1.FetchOptions.RecsMax := 100;
 FDQuery1.Open;
 // process rows
 
 FDQuery1.Disconnect;
 FDQuery1.FetchOptions.RecsSkip := 100;
 FDQuery1.Open;
 // process rows
 
 FDQuery1.Disconnect;
 FDQuery1.FetchOptions.RecsSkip := 200;
 FDQuery1.Open;
 // process rows

RecsSkip プロパティや RecsMax プロパティが指定されている場合、FireDAC では、可能であれば、元の SELECT コマンドを変更して TOP/ROWS やそれと似た句を適用します。


遅延取得

結果セットには、BLOB 列やネストしたデータセット列が含まれている場合があります。一般に、そのような列があると、結果セット取得の速度が落ちます。FireDAC では、そのような列の値が本当に必要になるまで、列の取得を先送りすることができます。FetchOptions.Items プロパティにより、それが以下のように制御されます。

  • fiBlobs が含まれていない場合は、BLOB 値の取得が先送りされます。FetchBlobs メソッドを呼び出すと、現在のデータセット レコードに対して BLOB 値の取得が実行されます。あるいは、Mode が fmManual でない場合は、BLOB 値の最初の読み取りで FetchBlobs が自動的に呼び出されます。
  • fiDetails が含まれていない場合は、ネストしたデータセットの取得が先送りされます。FetchDetails メソッドを呼び出すと、現在のレコードに対して、ネストしたデータセットの取得が実行されます。また、fiDetails でマスタ/詳細関係の処理も制御されます。

遅延取得 SQL コマンドの生成については、「更新コマンド生成」を参照してください。

メモ: FetchOptions.Items から fiBlobs または fiDetails を除外しても、SQL コマンドの SELECT リストは変更されません。DBMS が BLOB 値を値で受け渡す場合(たとえば Oracle LONG、MySQL、SQL Server、SQLite など)、それらの BLOB 値はネットワークを通じてクライアントに配信されます。ただし、クライアントのレコード キャッシュには格納されません。しかし、DBMS が BLOB 値を参照で受け渡す場合(たとえば Oracle CLOB/BLOB、Interbase、Firebird など)、それらの BLOB 値は配信も格納もされません。

行の再取得

アプリケーションでは、既存の結果セットの末尾に新しい結果セットを追加したり、行を再取得するなどの操作が必要なことがときどきあります。それには、FetchAgain メソッドを使用します。

メモ: データセットの表示を更新する場合は Refresh メソッドを使用します。

一般的な使用例

一般的な使用例とそれらに対応する FetchOptions 設定を以下の表に示します。

使用例 説明
限られたメモリ使用量で大量のレコードの取得時間を最小限に抑える場合 CursorKind = ckDefault または ckForwardOnly Mode = fmOnDemand RowsetSize = 1000 Unidirectional = True
クエリを開いたときに取得を先送りし取得時間を最小限に抑える場合 CursorKind = ckDefault Mode = fmAll RowsetSize = 1000
クエリを開いたときの取得の先送りを最小限に抑える場合 CursorKind = ckDynamic Mode = fmOnDemand RowsetSize = 50 Items から fiMeta を除外
読み取り専用データセットの場合 Items から fiMeta を除外、または UpdateOptions.RequestLive を False に設定
複数の結果セットを扱うバッチ コマンドの場合 AutoClose = False
複数の大きい BLOB 値を含む大量のレコードの取得時間を、限られたメモリ使用量で最小限に抑える場合 Items から fiBlobs を除外。上記との組み合わせ

関連項目