行の取得(FireDAC)
コマンドの操作(FireDAC) への移動
カーソルの処理
SQL コマンドが実行され、その結果行が返される必要がある場合、DBMS では DBMS サーバー上にカーソルを作成します。アプリケーションでは、カーソルを使用してデータベースから行を取得します。DBMS によっては、いくつかの種類のカーソルがある場合があります。カーソルの種類を選択するには、FetchOptions.CursorKind プロパティを使用します。デフォルトでは、FireDAC は最速の種類のカーソル(ckAutomatic)を選択します。まず、このプロパティは、Microsoft SQL Server で効果があります。
DBMS カーソルは、それ自体がオープンされたトランザクション コンテキストに左右されます。詳細については、「トランザクションの管理」を参照してください。
行セット取得
行セットの取得では、1 回のネットワーク ラウンド トリップでサーバーから取得される、レコード数を指定することができます。これは、実行する SELECT 文ごとに個別に最適化することができるため、RowsetSize オプションを指定することで、ネットワーク ラウンド トリップの数を、最小限に抑えることができます。.
行セットのサイズは、FetchOptions.RowsetSize プロパティで制御されます。この数が大きいほど、FireDAC はより高速に結果のフルセットを取得しますが、次の行セットを取得するまでに遅延も大きくなります。また、「高い」値から開始すると、パフォーマンスは劣化し始めます。「高い」値は具体的には 2000-3000 ぐらいです。
- メモ: すべての DBMS が行セットの取得をサポートしているわけではありません。しかしながら、FireDAC は、速度を犠牲にして、この機能をエミュレートする機能があります。エミュレートされた行セットの取得は、実際の取得に比べ、50% の速度低下がみられます。
FireDAC は、FetchOptions.Mode プロパティに従って、行セットを取得します。
- fmOnDemand -- データセットが、直近に取得されたレコードより先にへ、現在の位置を移動しようとすると、行セットが自動的に取得されます。
- fmAll -- SQL コマンドが実行された直後に、すべての行セットが自動的に取得されます。これは、FetchAll メソッドの呼び出しと同等です。
- fmManual -- プログラマは、手動で行セットを取得する際には、メソッド FetchNext や FetchAll を使用します。
- fmExactRecsMax -- SQL コマンドが実行された直後に、すべての行セットが自動的に取得されます。 行数が FetchOptions.RecsMax と異なる場合には、例外が発生します。
FetchOptions.Unidirectional が True の場合、次の行セットを取得する前に、以前の行がメモリから破棄されます。これにより、大きな結果セットを取得する際に、PC のメモリを保持することができます。
すべてのレコードが取得されたら、TFDDataSet.SourceEOF は True に設定され、FetchOptions.AutoClose に基づき、基礎となっているコマンドはクローズされます。これは、データセット自身はクローズしません。
- メモ: 詳細については、「コマンド バッチ」を参照してください。
アプリケーションでは、TFDDataSet.AfterGetRecord イベント ハンドラを使って、取得した各レコードにアクセスできます。
行のページング
FetchOptions.RecsSkip と RecsMax により、結果セットのページングが可能です。カーソルが開かれた後、最初の 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 が含まれていない場合は、FireDAC は、BLOB 値の取得を遅延します。FetchBlobs メソッドは、現在のデータセット レコードに対する BLOB 値の取得を実行します。あるいは、BLOB 値の最初の読み取りで、自動的に FetchBlobs を呼び出します(Mode <> fmManual の場合)。
- fiDetails が含まれていない場合、FireDAC は、ネストしたデータセットの取得を遅延します。 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 fiMeta を Items から除外。 |
読み取り専用データセットの場合 | fiMeta を Items から除外。または、UpdateOptions.RequestLive を False に設定。 |
複数の結果セットを扱うバッチ コマンドの場合 | AutoClose = False |
複数の大きい BLOB 値を含む大量のレコードの取得時間を、限られたメモリ使用量で最小限に抑える場合 | fiBlobs を Items から除外。上記との組み合わせ。 |