結果データのフェッチ
適用対象: SQL Server Azure SQL Database Azure SQL Managed Instance Azure Synapse Analytics Analytics Platform System (PDW)
ODBC アプリケーションでは、結果データのフェッチを 3 つの方法で実行できます。
最初のオプションは、 SQLBindCol に基づいています。 結果セットをフェッチする前に、アプリケーションは SQLBindCol を使用して、結果セット内の各列をプログラム変数にバインドします。 列がバインドされると、ドライバーは、アプリケーションが SQLFetch または SQLFetchScroll を呼び出すたびに、現在の行のデータを結果セット列にバインドされた変数に転送します。 結果セット列のデータ型とプログラム変数のデータ型が異なる場合、ドライバーによってデータ変換が処理されます。 アプリケーションSQL_ATTR_ROW_ARRAY_SIZE 1 より大きい値を設定している場合は、結果列を変数の配列にバインドできます。これはすべて、 SQLFetchScroll の呼び出しごとに入力されます。
2 番目のオプションは、 SQLGetData に基づいています。 アプリケーションは、 SQLBindCol を使用して結果セット列をプログラム変数にバインドしません。 SQLFetch を呼び出すたびに、アプリケーションは結果セット内の各列に対して SQLGetData を 1 回呼び出します。 SQLGetData は、特定の結果セット列から特定のプログラム変数にデータを転送するようにドライバーに指示し、列と変数のデータ型を指定します。 そのため、結果列のデータ型とプログラム変数のデータ型が異なる場合は、ドライバーでデータを変換できます。 Text、 ntext、および image 列は通常、プログラム変数に収まらない大きさですが、 SQLGetData を使用して取得できます。 結果列の text、 ntext、または image データがプログラム変数より大きい場合、 SQLGetData はSQL_SUCCESS_WITH_INFOと SQLSTATE 01004 (文字列データ、右切り捨て) を返します。 SQLGetData の連続する呼び出しは、text または image データの連続したチャンクを返します。 データの末尾に達すると、 SQLGetData はSQL_SUCCESSを返します。 SQL_ATTR_ROW_ARRAY_SIZE に 1 よりも大きい値を指定すると、フェッチのたびに行セットが返されます。 SQLGetDataを使用する前に、まず SQLSetPos を使用して、行セット内の特定の行を現在の行として指定する必要があります。
3 番目のオプションは、 SQLBindCol と SQLGetData の組み合わせを使用することです。 たとえば、アプリケーションは、結果セットの最初の 10 列をバインドしてから、各フェッチで SQLGetData を 3 回呼び出して、3 つのバインドされていない列からデータを取得できます。 これは通常、結果セットに 1 つ以上の text または image 列が含まれている場合に使用されます。
結果セットに対して設定されたカーソル オプションに応じて、アプリケーションは SQLFetchScroll のスクロール オプションを使用して結果セットをスクロールすることもできます。
SQLBindColを使用して結果セット列をプログラム変数にバインドすることは、
このロジックにより、異なるパラメーターを指定して同じ SELECT ステートメントを何度も実行することで、効率を上げることができます。 結果セットは同じ構造を保持するため、結果セットを 1 回バインドし、すべての SELECT ステートメントを処理してから、最後の実行後に fOption をSQL_UNBINDに設定して SQLFreeStmt を呼び出すことができます。 SQLBindCol を呼び出して結果セット内の列をバインドしないでください。前のバインディングを解放するために、最初に fOption SQL_UNBIND に設定SQLFreeStmtを呼び出す必要があります。
SQLBindCol を使用する場合は、行方向または列方向のバインドを実行できます。 行方向のバインドの方が、列方向のバインドよりも処理がやや高速になります。
SQLGetData を使用すると、SQLBindCol を使用して結果セット列をバインドする代わりに、列単位でデータを取得できます。
SQLGetData、SQLBindCol、SQLBindParameter など、プログラム変数との間でのデータの移動を処理する ODBC 関数では、暗黙的なデータ型変換がサポートされます。 たとえば、整数列を文字列プログラム変数にバインドするアプリケーションでは、プログラム変数にデータを格納する前に、ドライバーが自動的にそのデータを整数から文字に変換します。
アプリケーションでのデータ変換は最小限に抑える必要があります。 列やパラメーターは、アプリケーションでの処理にデータ変換が必要な場合を除き、同じデータ型のプログラム変数にバインドする必要があります。 ただし、あるデータ型から別のデータ型に変換する必要がある場合は、アプリケーションでのデータ変換よりもドライバーによるデータ変換の方が効率的です。 SQL Server Native Client ODBC ドライバーは、通常、ネットワーク バッファーからアプリケーションの変数に直接データを転送するだけです。 データ変換を行うようにドライバーに要求すると、ドライバーはデータをバッファーに格納し、CPU サイクルを使用してデータを変換します。
プログラム変数は、 text、 ntext、および image データを除き、列から転送されるデータを保持するのに十分な大きさにする必要があります。 結果セットのデータを取得してそのデータを変数に格納するときに、その変数が小さすぎてデータを保持できない場合、ドライバーは警告を生成します。 その結果、ドライバーでは警告メッセージ用のメモリを割り当て、ドライバーとアプリケーションの両方で、警告メッセージの処理やエラーの処理に CPU サイクルが必要になります。 アプリケーションでは、取得するデータを保持するのに十分なサイズの変数を割り当てるか、選択リストで SUBSTRING 関数を使用して結果セット内の列のサイズを小さくする必要があります。
SQL_C_DEFAULT を使用して C 変数のデータ型を指定する場合は注意が必要です。 SQL_C_DEFAULT は、C 変数のデータ型と、列やパラメーターの SQL データ型を一致させることを指定します。 ntext、nchar、または nvarchar 列にSQL_C_DEFAULTが指定されている場合、Unicode データがアプリケーションに返されます。 そのため、アプリケーションが Unicode データを処理するようにコーディングされていないと、さまざまな問題が発生する可能性があります。 uniqueidentifier (SQL_GUID) データ型でも同じ種類の問題が発生する可能性があります。
text、ntext、および image データは通常、1 つのプログラム変数に収まらない大きすぎて、通常は SQLBindCol ではなく SQLGetData で処理されます。 サーバー カーソルを使用する場合、SQL Server Native Client ODBC ドライバーは、行のフェッチ時に、バインドされていない text、 ntext、または image 列のデータを送信しないように最適化されています。 text、ntext、またはimageデータは、アプリケーションが列に対してSQLGetDataを発行するまで、サーバーから実際には取得されません。
この最適化をアプリケーションに適用して、ユーザーがカーソルを上下にスクロールしている間、 text、 ntext、または image データを表示しないようにすることができます。 ユーザーが行を選択すると、アプリケーションは SQLGetData を呼び出して、 text、 ntext、または image データを取得できます。 これにより、ユーザーが選択しない行の テキスト、 ntext、または image データの送信が保存され、非常に大量のデータの転送を保存できます。