次の方法で共有


結果データの取得

ODBC アプリケーションには、結果データをフェッチするための 3 つのオプションがあります。

最初のオプションは SQLBindCol に基づいています。 結果セットをフェッチする前に、アプリケーションは SQLBindCol を使用して、結果セット内の各列をプログラム変数にバインドします。 列がバインドされると、アプリケーションが SQLFetch または SQLFetchScroll を呼び出すたびに、ドライバーは現在の行のデータを結果セット列にバインドされた変数に転送します。 結果セットの列とプログラム変数のデータ型が異なる場合、ドライバーはデータ変換を処理します。 アプリケーションが 1 より大きい値SQL_ATTR_ROW_ARRAY_SIZE設定されている場合、結果列を変数の配列にバインドできます。これはすべて 、SQLFetchScroll の呼び出しごとに入力されます。

2 番目のオプションは SQLGetData に基づいています。 アプリケーションでは、 SQLBindCol を使用して結果セット列をプログラム変数にバインドしません。 SQLFetch を呼び出すたびに、アプリケーションは結果セット内の列ごとに 1 回 SQLGetData を呼び出します。 SQLGetData は、特定の結果セット列から特定のプログラム変数にデータを転送するようにドライバーに指示し、列と変数のデータ型を指定します。 これにより、結果列とプログラム変数のデータ型が異なる場合、ドライバーはデータを変換できます。 通常、テキストntextおよびイメージ の列は大きすぎてプログラム変数に収まりませんが、引き続き SQLGetData を使用して取得できます。 結果列の テキストn テキスト、または 画像 データがプログラム変数より大きい場合、 SQLGetData はSQL_SUCCESS_WITH_INFOおよび SQLSTATE 01004 (文字列データ、右切り捨て) を返します。 SQLGetData を連続して呼び出すと、テキストまたは画像データの連続するチャンクが返されます。 データの末尾に達すると、 SQLGetData はSQL_SUCCESSを返します。 SQL_ATTR_ROW_ARRAY_SIZEが 1 より大きい場合、各フェッチは行セット (行セット) を返します。 SQLGetData を使用する前に、まず SQLSetPos を使用して、行セット内の特定の行を現在の行として指定する必要があります。

3 番目のオプションは、 SQLBindColSQLGetData の組み合わせを使用することです。 たとえば、アプリケーションは、結果セットの最初の 10 列をバインドし、各フェッチで SQLGetData を 3 回呼び出して、3 つのバインドされていない列からデータを取得できます。 これは通常、結果セットに 1 つ以上の テキスト 列または 画像 列が含まれている場合に使用されます。

結果セットに対して設定されたカーソル オプションに応じて、アプリケーションは SQLFetchScroll のスクロール オプションを使用して結果セットをスクロールすることもできます。

SQLBindCol を使用して結果セット列をプログラム変数にバインドすることは、SQLBindCol によって ODBC ドライバーにメモリが割り当てられるため、コストがかかります。 結果列を変数にバインドする場合、SQLFreeHandle を呼び出してステートメント ハンドルを解放するか、fOption を SQL_UNBIND に設定して SQLFreeStmt を呼び出すまで、そのバインドは有効なままです。 ステートメントが完了しても、バインドは自動的に元に戻されません。

このロジックを使用すると、異なるパラメーターを使用して同じ SELECT ステートメントを複数回実行する処理を効果的に行うことができます。 結果セットは同じ構造を保持するため、結果セットを 1 回バインドし、すべての SELECT ステートメントを処理してから、最後の実行後に fOption を SQL_UNBIND に設定して SQLFreeStmt を呼び出すことができます。 SQLBindCol を呼び出して結果セット内の列をバインドしないでください。前のバインディングを解放するには、fOption を SQL_UNBIND に設定して SQLFreeStmt を最初に呼び出す必要があります。

SQLBindCol を使用する場合は、行方向または列方向のバインドを実行できます。 行方向のバインドは、列方向のバインドよりもやや高速です。

SQLBindCol を使用して結果セット列をバインドする代わりに、SQLGetData を使用して列単位でデータを取得できます。 結果セットに含まれる行数が少ない場合は、SQLBindCol の代わりに SQLGetData を使用する方が高速です。それ以外の場合、SQLBindCol は最適なパフォーマンスを提供します。 常に同じ変数セットにデータを配置しない場合は、常に再バインドするのではなく 、SQLGetData を使用する必要があります。 SQLGetData は、すべての列が SQLBindCol にバインドされた後、選択リスト内の列でのみ使用できます。 この列は、 SQLGetData を既に使用している列の後にも表示する必要があります。

SQLGetDataSQLBindColSQLBindParameter などのプログラム変数との間でのデータの移動を処理する ODBC 関数は、暗黙的なデータ型変換をサポートします。 たとえば、アプリケーションが整数列を文字列プログラム変数にバインドする場合、ドライバーは、データをプログラム変数に配置する前に、データを整数から文字に自動的に変換します。

アプリケーションでのデータ変換は最小限に抑える必要があります。 アプリケーションによる処理にデータ変換が必要でない限り、アプリケーションは列とパラメーターを同じデータ型のプログラム変数にバインドする必要があります。 ただし、データをある型から別の型に変換する必要がある場合は、アプリケーションで行うよりも、ドライバーに変換を行う方が効率的です。 SQL Server Native Client ODBC ドライバーは、通常、ネットワーク バッファーからアプリケーションの変数に直接データを転送するだけです。 データ変換を実行するようにドライバーに要求すると、ドライバーは強制的にデータをバッファーし、CPU サイクルを使用してデータを変換します。

プログラム変数は、 テキストntextおよび画像 データを除き、列から転送されたデータを保持するのに十分な大きさにする必要があります。 アプリケーションが結果セット のデータを取得し、それを保持するには小さすぎる変数に配置しようとすると、ドライバーは警告を生成します。 これにより、ドライバーがメッセージのメモリを割り当てる必要があります。ドライバーとアプリケーションの両方が、メッセージの処理とエラー処理の実行に CPU サイクルを費やす必要があります。 アプリケーションは、取得するデータを保持するのに十分な大きさの変数を割り当てるか、選択リストの SUBSTRING 関数を使用して結果セット内の列のサイズを小さくする必要があります。

SQL_C_DEFAULTを使用して C 変数の型を指定する場合は、注意が必要です。 SQL_C_DEFAULTは、C 変数の型が列またはパラメーターの SQL データ型と一致することを指定します。 ntext、nchar、または nvarcharにSQL_C_DEFAULTを指定すると、Unicode データがアプリケーションに返されます。 これにより、アプリケーションが Unicode データを処理するようにコーディングされていない場合、さまざまな問題が発生する可能性があります。 uniqueidentifier (SQL_GUID) データ型でも同じ種類の問題が発生する可能性があります。

通常、textntext、およびイメージ データは大きすぎて 1 つのプログラム変数に収まりきらず、通常は SQLBindCol ではなく SQLGetData で処理されます。 サーバー カーソルを使用する場合、SQL Server Native Client ODBC ドライバーは、行のフェッチ時に非連結 テキストntext、または イメージ 列のデータを送信しないように最適化されています。 テキストntext、またはイメージ データは、アプリケーションが列に対して SQLGetData を発行するまで、サーバーから実際には取得されません。

この最適化をアプリケーションに適用して、ユーザーがカーソルを上下にスクロールしている間に テキストnテキストまたは画像 データを表示しないようにすることができます。 ユーザーが行を選択すると、アプリケーションは SQLGetData を呼び出して 、テキストntext、または イメージ データを取得できます。 これにより、ユーザーが選択していない行の テキストnテキスト、または 画像 データの送信が保存され、非常に大量のデータの送信を保存できます。

こちらもご覧ください

結果の処理 (ODBC)