SQLBindCol 関数

準拠
導入されたバージョン: ODBC 1.0 標準準拠: ISO 92

まとめ
SQLBindCol は 、アプリケーション データ バッファーを結果セット内の列にバインドします。

構文

  
SQLRETURN SQLBindCol(  
      SQLHSTMT       StatementHandle,  
      SQLUSMALLINT   ColumnNumber,  
      SQLSMALLINT    TargetType,  
      SQLPOINTER     TargetValuePtr,  
      SQLLEN         BufferLength,  
      SQLLEN *       StrLen_or_IndPtr);  

引数

StatementHandle
[入力]ステートメント ハンドル。

ColumnNumber
[入力]バインドする結果セット列の数。 列の番号は 0 から始まる列の順序で増やされます。列 0 はブックマーク列です。 ブックマークが使用されていない場合(つまり、SQL_ATTR_USE_BOOKMARKSステートメント属性はSQL_UB_OFFに設定され、列番号は 1 から始まります。

TargetType
[入力]*TargetValuePtr バッファーの C データ型の識別子。 SQLFetch、SQLFetchScrollSQLBulkOperations、または SQLSetPos を使用してデータ ソースからデータを取得する場合、ドライバーはデータをこの型に変換します。SQLBulkOperations または SQLSetPos を使用してデータ ソースにデータを送信すると、ドライバーはこの型からデータを変換します。 有効な C データ型と型識別子の一覧については、「付録 D: データ型」の「C データ型 」セクションを参照してください。

TargetType 引数が間隔データ型の場合、ARD の SQL_DESC_DATETIME_INTERVAL_PRECISION フィールドと SQL_DESC_PRECISION フィールドで設定される既定の間隔の先頭の有効桁数 (2) と既定の間隔の秒の有効桁数 (6) がデータに使用されます。 TargetType 引数がSQL_C_NUMERICの場合、ARD の SQL_DESC_PRECISION フィールドと SQL_DESC_SCALE フィールドに設定されている既定の有効桁数 (ドライバー定義) と既定のスケール (0) がデータに使用されます。 既定の有効桁数または小数点以下桁数が適切でない場合、アプリケーションは SQLSetDescField または SQLSetDescRec の呼び出しによって適切な記述子フィールドを明示的に設定 する必要があります。

拡張 C データ型を指定することもできます。 詳細については、「 ODBC の C データ型」を参照してください。

TargetValuePtr
[遅延入出力]列にバインドするデータ バッファーへのポインター。 SQLFetchSQLFetchScroll は、 このバッファー内のデータを返します。 SQLBulkOperations は、操作がSQL_FETCH_BY_BOOKMARKされると、このバッファー内のデータを返します。Operation がSQL_ADDまたはSQL_UPDATE_BY_BOOKMARKされると、このバッファーからデータが取得されます。 SQLSetPos は、Operation がSQL_REFRESHされると、このバッファー内のデータを返します。Operation がSQL_UPDATEされると、このバッファーからデータが取得されます。

TargetValuePtr が null ポインターの場合、ドライバーは列のデータ バッファーをバインド解除します。 アプリケーションは、SQL_UNBIND オプションを使用して SQLFreeStmt を呼び出すことで、すべての列のバインドを解除できます。 SQLBindCol の呼び出しの TargetValuePtr 引数が null ポインターであるが、StrLen_or_IndPtr引数が有効な値である場合、アプリケーションは列のデータ バッファーをバインド解除できますが、列の長さ/インジケーター バッファーはバインドされたままです。

BufferLength
[入力]*TargetValuePtr バッファーの長さ (バイト単位)。

ドライバーは BufferLength を使用して、文字データやバイナリ データなどの可変長データを返すときに、*TargetValuePtr バッファーの末尾を超えて書き込むのを避けます。 *TargetValuePtr に文字データを返すときに、ドライバーが null 終端文字をカウントしていることに注意してください。 *したがって、TargetValuePtr には null 終端文字の領域が含まれている必要があります。または、ドライバーはデータを切り捨てます。

ドライバーが整数や日付構造などの固定長データを返す場合、ドライバーは BufferLength を無視し、バッファーがデータを保持するのに十分な大きさであると仮定します。 そのため、アプリケーションで固定長データに十分な大きさのバッファーを割り当てることが重要です。または、ドライバーはバッファーの末尾を超えて書き込みます。

SqlBindCol は、 BufferLength が 0 未満の場合は SQLSTATE HY090 (文字列またはバッファーの長さが無効) を返しますが、 BufferLength が 0 の場合は返しません。 ただし、 TargetType で文字型が指定されている場合、ISO CLI 準拠ドライバーは SQLSTATE HY090 (文字列またはバッファーの長さが無効) を返すため、アプリケーションで BufferLength を 0 に設定しないでください。

StrLen_or_IndPtr
[遅延入出力]列にバインドする長さ/インジケーター バッファーへのポインター。 SQLFetchSQLFetchScroll は、このバッファー内の値を返します。 SQLBulkOperations は、 Operation がSQL_ADD、SQL_UPDATE_BY_BOOKMARK、またはSQL_DELETE_BY_BOOKMARKされるときに、このバッファーから値を取得します。 SQLBulkOperations は、 Operation がSQL_FETCH_BY_BOOKMARKされると、このバッファー内の値を返します。 SQLSetPos は、Operation がSQL_REFRESHされると、このバッファー内の値を返します。Operation がSQL_UPDATEされると、このバッファーから値が取得されます。

SQLFetchSQLFetchScrollSQLBulkOperationsおよび SQLSetPos は、長さ/インジケーター バッファーで次の値を返すことができます。

  • 返すデータの長さ

  • SQL_NO_TOTAL

  • SQL_NULL_DATA

アプリケーションは、 SQLBulkOperations または SQLSetPos で使用するために、長さ/インジケーター バッファーに次の値を配置できます。

  • 送信されるデータの長さ

  • SQL_NTS

  • SQL_NULL_DATA

  • SQL_DATA_AT_EXEC

  • SQL_LEN_DATA_AT_EXEC マクロの結果

  • SQL_COLUMN_IGNORE

標識バッファーと長さバッファーが別個のバッファーである場合、標識バッファーはSQL_NULL_DATAのみを戻すことができますが、長さバッファーは他のすべての値を返すことができます。

詳細については、「 SQLBulkOperations 関数SQLFetch 関数SQLSetPos 関数、および 長さ/インジケーター値の使用」を参照してください。

StrLen_or_IndPtrが null ポインターの場合、長さまたはインジケーター値は使用されません。 これは、データをフェッチするときにエラーであり、データが NULL です。

アプリケーション が 64 ビット オペレーティング システムで実行される場合は、ODBC 64 ビット情報を参照してください。

戻り値

SQL_SUCCESS、SQL_SUCCESS_WITH_INFO、SQL_ERROR、またはSQL_INVALID_HANDLE。

診断

SQLBindCol がSQL_ERRORまたはSQL_SUCCESS_WITH_INFOを返すときは、関連付けられている SQLSTATE 値を取得するには、SQL_HANDLE_STMT の HandleTypeStatementHandleハンドルを使用して SQLGetDiagRec を呼び出します。 次の表に、 SQLBindCol によって通常返される SQLSTATE 値の一覧を示し、この関数のコンテキストでそれぞれについて説明します。ドライバー マネージャーによって返される SQLSTATEs の説明の前に表記 "(DM)" が付きます。 特に記載がない限り、各 SQLSTATE 値に関連付けられている戻りコードはSQL_ERRORされます。

SQLSTATE エラー 説明
01000 一般的な警告 ドライバー固有の情報メッセージ。 (関数はSQL_SUCCESS_WITH_INFOを返します。
07006 制限付きデータ型属性違反 (DM) ColumnNumber 引数が 0 で、 TargetType 引数がSQL_C_BOOKMARKまたはSQL_C_VARBOOKMARKされませんでした。
07009 記述子インデックスが無効です 引数 ColumnNumber に指定された値が、結果セット内の列の最大数を超えました。
HY000 一般的なエラー 特定の SQLSTATE がなく、実装固有の SQLSTATE が定義されていないエラーが発生しました。 *MessageText バッファー内の SQLGetDiagRec によって返されるエラー メッセージは、エラーとその原因について説明します。
HY001 メモリ割り当てエラー ドライバーは、関数の実行または完了をサポートするために必要なメモリを割り当てませんでした。
HY003 無効なアプリケーション バッファーの種類 TargetType 引数は、有効なデータ型でもSQL_C_DEFAULTでもありません。
HY010 関数シーケンス エラー (DM) StatementHandle に関連付けられている接続ハンドルに対して非同期に実行される関数が呼び出されました。 この非同期関数は、 SQLBindCol が呼び出されたときにまだ実行されていました。

(DM) SQLExecuteSQLExecDirect、または SQLMoreResultsStatementHandle に対して呼び出され、SQL_PARAM_DATA_AVAILABLE返されました。 この関数は、すべてのストリーミング パラメーターに対してデータが取得される前に呼び出されました。

(DM) 非同期実行関数が StatementHandle に対して呼び出され、この関数が呼び出されたときにまだ実行されていました。

(DM) SQLExecuteSQLExecDirectSQLBulkOperations、または SQLSetPosStatementHandle に対して呼び出され、SQL_NEED_DATA返されました。 この関数は、実行時のすべてのデータ パラメーターまたは列に対してデータが送信される前に呼び出されました。
HY013 メモリ管理エラー メモリが不足している可能性があるため、基になるメモリ オブジェクトにアクセスできなかったため、関数呼び出しを処理できませんでした。
HY090 文字列またはバッファーの長さが無効です (DM) 引数 BufferLength に指定された値が 0 未満でした。

(DM) ドライバーは ODBC 2 でした。x ドライバー、 ColumnNumber 引数が 0 に設定され、引数 BufferLength に指定された値が 4 に等しくない。
HY117 不明なトランザクション状態が原因で接続が中断されます。 切断と読み取り専用の関数のみが許可されます。 (DM) 中断状態の詳細については、「 SQLEndTran 関数」を参照してください。
HYC00 省略可能な機能が実装されていません ドライバーまたはデータ ソースは、TargetType 引数と、対応する列のドライバー固有のSQLデータ型の組み合わせで指定された変換をサポートしていません。

引数 ColumnNumber は 0 で、ドライバーはブックマークをサポートしていません。

ドライバーは ODBC 2 のみをサポートします。x と引数 TargetType は次のいずれかでした。

SQL_C_NUMERIC SQL_C_SBIGINT SQL_C_UBIGINT

「付録 D: データ型」の C データ型に記載されている間隔 C データ型 のいずれか。

ドライバーは、3.50 より前のバージョンの ODBC のみをサポートし、引数 TargetType がSQL_C_GUIDされました。
HYT01 接続のタイムアウト 接続タイムアウト期間は、データ ソースが要求に応答する前に期限切れになりました。 接続タイムアウト期間は、 SQLSetConnectAttr (SQL_ATTR_CONNECTION_TIMEOUT) によって設定されます。
IM001 ドライバーは、この関数をサポートしていません。 (DM) StatementHandle に関連付けられているドライバーは、関数をサポートしていません。

コメント

SQLBindCol は、結果セット内の列をアプリケーションのデータ バッファーと長さ/インジケーター バッファーに関連付ける (または バインド する) ために使用されます。 アプリケーションが SQLFetchSQLFetchScroll、または SQLSetPos を呼び出してデータをフェッチすると、ドライバーは指定されたバッファー内のバインドされた列のデータを返します。詳細については、「 SQLFetch 関数」を参照してください。 アプリケーションが SQLBulkOperations を呼び出して行を更新または挿入するか 、SQLSetPos を呼び出して行を更新すると、ドライバーは指定されたバッファーからバインドされた列のデータを取得します。詳細については、 SQLBulkOperations 関数 または SQLSetPos 関数を参照してください。 バインドの詳細については、「 結果の取得 (基本)」を参照してください。

列からデータを取得するために列をバインドする必要はありません。 アプリケーションは 、SQLGetData を呼び出して列からデータを取得することもできます。 行の一部の列をバインドし、 SQLGetData を呼び出して他の列に対して呼び出すことは可能ですが、これにはいくつかの制限があります。 詳細については、「 SQLGetData」を参照してください。

列のバインド、バインド解除、および再バインド

列は、結果セットからデータがフェッチされた後でも、いつでもバインド、バインド解除、またはリバウンドできます。 新しいバインドは、次にバインディングを使用する関数が呼び出されるときに有効になります。 たとえば、アプリケーションが結果セット内の列をバインドし、 SQLFetch を呼び出すとします。 ドライバーは、バインドされたバッファー内のデータを返します。 次に、アプリケーションが列を別のバッファー セットにバインドするとします。 ドライバーは、新しくバインドされたバッファーに、フェッチされた行のデータを配置しません。 代わりに、 SQLFetch が再び呼び出されるまで待機し、新しくバインドされたバッファーに次の行のデータを配置します。

注意

ステートメント属性SQL_ATTR_USE_BOOKMARKSは、列を列 0 にバインドする前に常に設定する必要があります。 これは必須ではありませんが、強くお勧めします。

バインディング列

列をバインドするために、アプリケーションは SQLBindCol を 呼び出し、データ バッファーの列番号、型、アドレス、長さ、および長さ/インジケーター バッファーのアドレスを渡します。 これらのアドレスの使用方法については、このセクションで後述する「バッファー アドレス」を参照してください。 バインド列の詳細については、「 SQLBindCol の使用」を参照してください。

これらのバッファーの使用は遅延されます。つまり、アプリケーションは SQLBindCol でバインドしますが、ドライバーは他の関数 (SQLBulkOperations、SQLFetchSQLFetchScroll、または SQLSetPos) からアクセスします。 バインドが有効である限り、 SQLBindCol で指定されたポインターが有効なままであることを確認するのは、アプリケーションの責任です。 アプリケーションでこれらのポインターが無効になることを許可した場合 (たとえば、バッファーを解放し、有効であると想定する関数を呼び出すと、結果は未定義になります)。 詳細については、「 遅延バッファー」を参照してください。

バインドは、新しいバインドに置き換えられるか、列がバインドされていないか、ステートメントが解放されるまで有効なままになります。

列のバインド解除

単一の列をバインド解除するために、アプリケーションは ColumnNumber をその列の数に設定し、TargetValuePtr を null ポインターに設定して SQLBindCol を呼び出します。 ColumnNumber がバインドされていない列を参照している場合、SQLBindCol は引き続きSQL_SUCCESSを返します。

すべての列のバインドを解除するには、fOption を SQL_UNBIND に設定して SQLFreeStmt を呼び出します。 これは、ARD の SQL_DESC_COUNT フィールドを 0 に設定することでも実現できます。

列の再バインド

アプリケーションは、次の 2 つの操作のいずれかを実行してバインディングを変更できます。

  • SQLBindCol を呼び出して、既にバインドされている列の新しいバインドを指定します。 ドライバーは、古いバインディングを新しいバインディングで上書きします。

  • SQLBindCol へのバインド呼び出しで指定されたバッファー アドレスに追加するオフセットを指定します。 詳細については、次のセクション「バインディング オフセット」を参照してください。

バインディング オフセット

バインディング オフセットは、逆参照される前に、データ バッファーと長さ/インジケーター バッファーのアドレス ( TargetValuePtr および StrLen_or_IndPtr 引数で指定) に追加される値です。 オフセットを使用する場合、バインドはアプリケーションのバッファーのレイアウト方法の "テンプレート" であり、アプリケーションはオフセットを変更することで、この "テンプレート" をメモリのさまざまな領域に移動できます。 各バインドの各アドレスに同じオフセットが追加されるため、異なる列のバッファー間の相対オフセットは、バッファーの各セット内で同じである必要があります。 これは、行方向のバインドが使用される場合に常に当てはまります。アプリケーションでは、列方向のバインドが使用される場合にこれが当てはまるよう、バッファーを慎重にレイアウトする必要があります。

バインディング オフセットを使用すると、 SQLBindCol を呼び出して列を再バインドする場合と基本的に同じ効果があります。 違いは、 SQLBindCol の新しい呼び出しでは、データ バッファーと長さ/インジケーター バッファーの新しいアドレスを指定しますが、バインド オフセットを使用してもアドレスは変更されず、単にオフセットが追加されるということです。 アプリケーションは必要に応じて新しいオフセットを指定でき、このオフセットは常に最初にバインドされたアドレスに追加されます。 特に、オフセットが 0 に設定されている場合、またはステートメント属性が null ポインターに設定されている場合、ドライバーは最初にバインドされたアドレスを使用します。

バインディング・オフセットを指定するために、アプリケーションは SQL_ATTR_ROW_BIND_OFFSET_PTR ステートメント属性を SQLINTEGER バッファーのアドレスに設定します。 アプリケーションがバインドを使用する関数を呼び出す前に、このバッファーにオフセットをバイト単位で配置します。 使用するバッファーのアドレスを確認するために、ドライバーは、バインディング内のアドレスにオフセットを追加します。 アドレスとオフセットの合計は有効なアドレスである必要がありますが、オフセットが追加されるアドレスは有効である必要はありません。 バインディング オフセットの使用方法の詳細については、このセクションで後述する「バッファー アドレス」を参照してください。

配列のバインド

行セットのサイズ (SQL_ATTR_ROW_ARRAY_SIZE ステートメント属性の値) が 1 より大きい場合、アプリケーションは単一バッファーではなくバッファーの配列をバインドします。 詳細については、「 ブロック カーソル」を参照してください。

アプリケーションは、次の 2 つの方法で配列をバインドできます。

  • 配列を各列にバインドします。 各データ構造 (配列) には 1 つの列のデータが含まれているため、これは列 ごとのバインド と呼ばれます。

  • 行全体のデータを保持し、これらの構造体の配列をバインドする構造体を定義します。 各データ構造には 1 つの行のデータが含まれているため、これは 行ごとのバインド と呼ばれます。

バッファーの各配列には、行セットのサイズと同数以上の要素が必要です。

注意

アプリケーションは、アラインメントが有効であることを確認する必要があります。 配置に関する考慮事項の詳細については、「 配置」を参照してください。

列方向のバインド

列ごとのバインドでは、アプリケーションは個別のデータ配列と長さ/インジケーター配列を各列にバインドします。

列方向のバインドを使用するために、アプリケーションは最初に SQL_ATTR_ROW_BIND_TYPE ステートメント属性をSQL_BIND_BY_COLUMNに設定します。 (これが既定値です)。バインドする列ごとに、アプリケーションは次の手順を実行します。

  1. データ バッファー配列を割り当てます。

  2. 長さ/インジケーター バッファーの配列を割り当てます。

    注意

    列方向のバインドを使用するときにアプリケーションが記述子に直接書き込む場合は、長さとインジケーター データに個別の配列を使用できます。

  3. 次の引数を使用して SQLBindCol を呼び出します。

    • TargetType は、データ バッファー配列内の 1 つの要素の型です。

    • TargetValuePtr は、データ バッファー配列のアドレスです。

    • BufferLength は、データ バッファー配列内の 1 つの要素のサイズです。 データが固定長データの場合、 BufferLength 引数は無視されます。

    • StrLen_or_IndPtr は、長さ/インジケーター配列のアドレスです。

この情報の使用方法の詳細については、このセクションで後述する「バッファー アドレス」を参照してください。 列方向のバインドの詳細については、「 列方向のバインド」を参照してください。

行方向のバインド

行方向のバインドでは、バインドする各列のデータバッファーと長さ/インジケーター バッファーを含む構造体がアプリケーションによって定義されます。

行方向バインドを使用するには、アプリケーションで次の手順を実行します。

  1. 1 行のデータ (データバッファーと長さ/インジケーター バッファーの両方を含む) を保持する構造体を定義し、これらの構造体の配列を割り当てます。

    注意

    行方向のバインドを使用するときにアプリケーションが記述子に直接書き込む場合は、長さとインジケーター データに個別のフィールドを使用できます。

  2. SQL_ATTR_ROW_BIND_TYPE ステートメント属性を、1 行のデータを含む構造体のサイズ、または結果列をバインドするバッファーのインスタンスのサイズに設定します。 バインドされた列のアドレスが指定した長さでインクリメントされるときに、結果が次の行の同じ列の先頭を指すように、長さは、すべてのバインドされた列のスペースと構造体またはバッファーのパディングを含める必要があります。 ANSI C で sizeof 演算子を使用する場合、この動作は保証されます。

  3. バインドする列ごとに次の引数を指定して SQLBindCol を呼び出します。

    • TargetType は、列にバインドされるデータ バッファー メンバーの型です。

    • TargetValuePtr は、最初の配列要素のデータ バッファー メンバーのアドレスです。

    • BufferLength は、データ バッファー メンバーのサイズです。

    • StrLen_or_IndPtr は、バインドする長さ/インジケーター メンバーのアドレスです。

この情報の使用方法の詳細については、このセクションで後述する「バッファー アドレス」を参照してください。 列方向のバインドの詳細については、「 行方向のバインド」を参照してください。

バッファー アドレス

バッファー アドレスは、データまたは長さ/インジケーター バッファーの実際のアドレスです。 ドライバーは、バッファーに書き込む直前 (フェッチ時など) にバッファー アドレスを計算します。 次の数式から計算されます。この数式では、 TargetValuePtr 引数と StrLen_or_IndPtr 引数、バインド オフセット、および行番号で指定されたアドレスが使用されます。

バインドされたアドレス + バインド オフセット + ((行番号 - 1) x 要素サイズ)

ここで、数式の変数は、次の表に示すように定義されています。

変数 説明
バインドされたアドレス データ バッファーの場合、SQLBindColTargetValuePtr 引数で指定されたアドレス。

長さ/インジケーター バッファーの場合、SQLBindColStrLen_or_IndPtr引数で指定されたアドレス。 詳細については、「記述子と SQLBindCol」セクションの「追加コメント」を参照してください。

バインドされたアドレスが 0 の場合、前の数式で計算されたアドレスが 0 以外の場合でも、データ値は返されません。
バインディング オフセット 行方向のバインドを使用する場合は、SQL_ATTR_ROW_BIND_OFFSET_PTR ステートメント属性で指定されたアドレスに格納される値。

列方向のバインドが使用されている場合、または SQL_ATTR_ROW_BIND_OFFSET_PTR ステートメント属性の値が null ポインターの場合、 Binding Offset は 0 です。
Row Number 行セット内の行の 1 から始まる番号。 単一行フェッチの場合(既定値)、これは 1 です。
要素のサイズ バインドされた配列内の要素のサイズ。

列ごとのバインドを使用する場合、これは長さ/インジケーター バッファーの sizeof(SQLINTEGER) です。 データ バッファーの場合、データ型が可変長の場合は SQLBindColBufferLength 引数の値、データ型が固定長の場合はデータ型のサイズです。

行方向のバインドを使用する場合、これはデータ バッファーと長さ/インジケーター バッファーの両方のSQL_ATTR_ROW_BIND_TYPEステートメント属性の値です。

記述子と SQLBindCol

次のセクションでは、 SQLBindCol が 記述子とやり取りする方法について説明します。

注意事項

1 つのステートメントに対して SQLBindCol を呼び出すと、他のステートメントに影響する可能性があります。 これは、ステートメントに関連付けられている ARD が明示的に割り当てられ、他のステートメントにも関連付けられている場合に発生します。 SQLBindCol は記述子を変更するため、変更は、この記述子が関連付けられているすべてのステートメントに適用されます。 これが必要な動作でない場合、アプリケーションは SQLBindCol を呼び出す前に、他のステートメントからこの記述子の関連付けを解除する必要があります。

引数のマッピング

概念的には、 SQLBindCol は 次の手順を順番に実行します。

  1. SQLGetStmtAttr を呼び出して ARD ハンドルを取得します。

  2. SQLGetDescField を呼び出してこの記述子のSQL_DESC_COUNT フィールドを取得し、ColumnNumber 引数の値が SQL_DESC_COUNT の値を超えた場合は、SQLSetDescField を呼び出して、SQL_DESC_COUNTの値を ColumnNumber に増やします。

  3. SQLSetDescField を複数回呼び出して、ARD の次のフィールドに値を割り当てます。

    • targetType が datetime または interval サブタイプの簡潔な識別子の 1 つである場合、SQL_DESC_TYPEをそれぞれ SQL_DATETIME または SQL_INTERVAL に設定する点を除き、SQL_DESC_TYPEとSQL_DESC_CONCISE_TYPEを TargetType の値に設定します。SQL_DESC_CONCISE_TYPEを簡潔な識別子に設定します。を使用して、対応する datetime または interval サブコードにSQL_DESC_DATETIME_INTERVAL_CODEを設定します。

    • TargetType に応じて、1 つ以上のSQL_DESC_LENGTH、SQL_DESC_PRECISION、SQL_DESC_SCALE、およびSQL_DESC_DATETIME_INTERVAL_PRECISIONを設定します。

    • SQL_DESC_OCTET_LENGTH フィールドを BufferLength の値に設定します。

    • SQL_DESC_DATA_PTR フィールドを TargetValuePtr の値に設定します。

    • SQL_DESC_INDICATOR_PTR フィールドを StrLen_or_IndPtrの値に設定します。 (次の段落を参照)。

    • SQL_DESC_OCTET_LENGTH_PTRフィールドを StrLen_or_IndPtrの値に設定します。 (次の段落を参照)。

StrLen_or_IndPtr引数が参照する変数は、インジケーターと長さの両方の情報に使用されます。 フェッチで列の null 値が検出されると、この変数にSQL_NULL_DATAが格納されます。それ以外の場合は、この変数にデータ長が格納されます。 StrLen_or_IndPtrとして null ポインターを渡すと、フェッチ操作でデータの長さが返されなくなりますが、null 値が検出され、SQL_NULL_DATAを返す方法がない場合、フェッチは失敗します。

SQLBindCol の呼び出しが失敗した場合、ARD で設定された記述子フィールドの内容は未定義になり、ARD の SQL_DESC_COUNT フィールドの値は変更されません。

COUNT フィールドの暗黙的なリセット

SQLBindCol は、SQL_DESC_COUNTの値が増加する場合にのみ、 引数 ColumnNumber の値にSQL_DESC_COUNTを設定します。 TargetValuePtr 引数の値が null ポインターで、ColumnNumber 引数の値がSQL_DESC_COUNTと等しい場合 (つまり、上限の列のバインドを解除する場合)、SQL_DESC_COUNTは残りの最も高いバインド列の数に設定されます。

SQL_DEFAULTに関する注意事項

列データを正常に取得するには、アプリケーションがアプリケーション バッファー内のデータの長さと開始点を正しく判断する必要があります。 アプリケーションが明示的な TargetType を指定すると、アプリケーションの誤認識が簡単に検出されます。 ただし、アプリケーションで SQL_DEFAULT の TargetType を指定する場合、 SQLBindCol は、メタデータへの変更から、またはコードを別の列に適用することによって、アプリケーションが意図したデータ型とは異なるデータ型の列に適用できます。 この場合、アプリケーションは、フェッチされた列データの開始または長さを常に決定するとは限りません。 これにより、レポートされないデータ エラーやメモリ違反が発生する可能性があります。

コード例

次の例では、アプリケーションは Customers テーブルで SELECT ステートメントを実行して、名前で並べ替えられた顧客 ID、名前、電話番号の結果セットを返します。 次に 、SQLBindCol を 呼び出して、データの列をローカル バッファーにバインドします。 最後に、アプリケーションは SQLFetch を使用してデータの各行をフェッチし、各顧客の名前、ID、電話番号を出力します。

その他のコード例については、「 SQLBulkOperations 関数SQLColumns 関数SQLFetchScroll 関数および SQLSetPos 関数」を参照してください。

// SQLBindCol_ref.cpp  
// compile with: odbc32.lib  
#include <windows.h>  
#include <stdio.h>  
  
#define UNICODE  
#include <sqlext.h>  
  
#define NAME_LEN 50  
#define PHONE_LEN 60
  
void show_error() {  
   printf("error\n");  
}  
  
int main() {  
   SQLHENV henv;  
   SQLHDBC hdbc;  
   SQLHSTMT hstmt = 0;  
   SQLRETURN retcode;  
   SQLWCHAR szName[NAME_LEN], szPhone[PHONE_LEN], sCustID[NAME_LEN];  
   SQLLEN cbName = 0, cbCustID = 0, cbPhone = 0;  
  
   // Allocate environment handle  
   retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);  
  
   // Set the ODBC version environment attribute  
   if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
      retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER*)SQL_OV_ODBC3, 0);   
  
      // Allocate connection handle  
      if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
         retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);  
  
         // Set login timeout to 5 seconds  
         if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
            SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);  
  
            // Connect to data source  
            retcode = SQLConnect(hdbc, (SQLWCHAR*) L"NorthWind", SQL_NTS, (SQLWCHAR*) NULL, 0, NULL, 0);  
  
            // Allocate statement handle  
            if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {   
               retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);   
  
               retcode = SQLExecDirect(hstmt, (SQLWCHAR *) L"SELECT CustomerID, ContactName, Phone FROM CUSTOMERS ORDER BY 2, 1, 3", SQL_NTS);  
               if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
  
                  // Bind columns 1, 2, and 3  
                  retcode = SQLBindCol(hstmt, 1, SQL_C_WCHAR, &sCustID, 100, &cbCustID);  
                  retcode = SQLBindCol(hstmt, 2, SQL_C_WCHAR, szName, NAME_LEN, &cbName);  
                  retcode = SQLBindCol(hstmt, 3, SQL_C_WCHAR, szPhone, PHONE_LEN, &cbPhone);   
  
                  // Fetch and print each row of data. On an error, display a message and exit.  
                  for (int i=0 ; ; i++) {  
                     retcode = SQLFetch(hstmt);  
                     if (retcode == SQL_ERROR || retcode == SQL_SUCCESS_WITH_INFO)  
                        show_error();  
                     if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)  
                     {
                        //replace wprintf with printf
                        //%S with %ls
                        //warning C4477: 'wprintf' : format string '%S' requires an argument of type 'char *'
                        //but variadic argument 2 has type 'SQLWCHAR *'
                        //wprintf(L"%d: %S %S %S\n", i + 1, sCustID, szName, szPhone);  
                        printf("%d: %ls %ls %ls\n", i + 1, sCustID, szName, szPhone);  
                    }    
                     else  
                        break;  
                  }  
               }  
  
               // Process data  
               if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
                  SQLCancel(hstmt);  
                  SQLFreeHandle(SQL_HANDLE_STMT, hstmt);  
               }  
  
               SQLDisconnect(hdbc);  
            }  
  
            SQLFreeHandle(SQL_HANDLE_DBC, hdbc);  
         }  
      }  
      SQLFreeHandle(SQL_HANDLE_ENV, henv);  
   }  
}  

ODBC プログラムのサンプル」も参照してください。

対象 解決方法については、
結果セット内の列に関する情報を返す SQLDescribeCol 関数
データブロックのフェッチまたは結果セットのスクロール SQLFetchScroll 関数
複数行のデータをフェッチする SQLFetch 関数
ステートメントでの列バッファーの解放 SQLFreeStmt 関数
データの列の一部またはすべてをフェッチする SQLGetData 関数
結果セット列の数を返す SQLNumResultCols 関数

参照

ODBC API リファレンス
ODBC ヘッダー ファイル