SQLBindCol 関数
準拠
導入されたバージョン: ODBC 1.0 Standards Compliance: 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、SQLFetchScroll、SQLBulkOperations、または SQLSetPos を使用してデータ ソースからデータを取得する場合、ドライバーはデータをこの型に変換します。SQLBulkOperations または SQLSetPos を使用してデータ ソースにデータを送信すると、ドライバーはこの型のデータを変換します。 有効な C データ型と型識別子の一覧については、「付録 D: データ型」の「C データ型 」セクションを参照してください。
TargetType 引数が間隔データ型の場合、既定の間隔の先頭の有効桁数 (2) と既定の間隔の秒の有効桁数 (6) は、それぞれ ARD の SQL_DESC_DATETIME_INTERVAL_PRECISION フィールドと SQL_DESC_PRECISION フィールドで設定されているデータに使用されます。 TargetType 引数がSQL_C_NUMERICの場合は、ARD の SQL_DESC_PRECISION フィールドと SQL_DESC_SCALE フィールドで設定されている既定の有効桁数 (ドライバー定義) と既定の小数点以下桁数 (0) がデータに使用されます。 既定の有効桁数または小数点以下桁数が適切でない場合、アプリケーションは SQLSetDescField または SQLSetDescRec の呼び出しによって適切な記述子フィールドを明示的に設定 する必要があります。
拡張 C データ型を指定することもできます。 詳細については、「ODBC の C データ型」を参照してください。
TargetValuePtr
[遅延入出力]列にバインドするデータ バッファーへのポインター。 SQLFetch と SQLFetchScroll は、このバッファー内のデータを返します。 SQLBulkOperations は 、Operation が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 を無視し、バッファーがデータを保持するのに十分な大きさであると想定します。 そのため、アプリケーションで固定長データに十分な大きさのバッファーを割り当てるか、ドライバーがバッファーの末尾を超えて書き込む必要があります。
BufferLength が 0 未満の場合、SQLBindCol は SQLSTATE HY090 (文字列またはバッファーの長さが無効) を返しますが、BufferLength が 0 の場合は返しません。 ただし、 TargetType で文字型が指定されている場合、ISO CLI 準拠ドライバーは SQLSTATE HY090 (文字列またはバッファーの長さが無効) を返すので、アプリケーションで BufferLength を 0 に設定しないでください。
StrLen_or_IndPtr
[遅延入出力]列にバインドする長さ/インジケーター バッファーへのポインター。 SQLFetch と SQLFetchScroll は、このバッファー内の値を返します。 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されると、このバッファーから値が取得されます。
SQLFetch、 SQLFetchScroll、 SQLBulkOperations、 および 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の HandleType と StatementHandle の Handle を指定して SQLGetDiagRec を呼び出します。 次の表に、 SQLBindCol によって通常返される SQLSTATE 値の一覧を示し、この関数のコンテキストでそれぞれについて説明します。表記 "(DM)" は、ドライバー マネージャーによって返される SQLSTATEs の説明の前にあります。 特に明記されていない限り、各 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) StatementHandle に対して SQLExecute、SQLExecDirect、または SQLMoreResults が呼び出され、SQL_PARAM_DATA_AVAILABLE返されました。 この関数は、ストリーミングされたすべてのパラメーターのデータが取得される前に呼び出されました。 (DM) 非同期実行関数が StatementHandle に対して呼び出され、この関数が呼び出されたときにはまだ実行されていました。 (DM) StatementHandle に対して SQLExecute、SQLExecDirect、SQLBulkOperations、または SQLSetPos が呼び出され、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 は、結果セット内 の列を アプリケーションのデータ バッファーと長さ/インジケーター バッファーに関連付ける(バインドする)ために使用されます。 アプリケーションが SQLFetch、SQLFetchScroll、または SQLSetPos を呼び出してデータをフェッチすると、ドライバーは指定されたバッファー内のバインドされた列のデータを返します。詳細については、「SQLFetch 関数」を参照してください。 アプリケーションが SQLBulkOperations を呼び出して行を更新または挿入するか 、SQLSetPos を 呼び出して行を更新すると、ドライバーは指定されたバッファーからバインドされた列のデータを取得します。詳細については、「 SQLBulkOperations 関数」 または 「SQLSetPos 関数」を参照してください。 バインドの詳細については、「 結果の取得 (Basic)」を参照してください。
列からデータを取得するために列をバインドする必要はありません。 アプリケーションでは、 SQLGetData を呼び出して列からデータを取得することもできます。 行の一部の列をバインドし、他の列に 対して SQLGetData を呼び出すことは可能ですが、これはいくつかの制限の対象となります。 詳細については、「 SQLGetData」を参照してください。
列のバインド、バインド解除、および再バインド
列は、結果セットからデータがフェッチされた後でも、いつでもバインド、バインド解除、またはリバウンドできます。 新しいバインディングは、次にバインディングを使用する関数が呼び出されるときに有効になります。 たとえば、アプリケーションが結果セット内の列をバインドし、 SQLFetch を呼び出すとします。 ドライバーは、バインドされたバッファー内のデータを返します。 次に、アプリケーションが列を別のバッファー セットにバインドするとします。 ドライバーは、フェッチされた行のデータを新しくバインドされたバッファーに配置しません。 代わりに、 SQLFetch が再度呼び出されるまで待機し、新しくバインドされたバッファーに次の行のデータを配置します。
Note
ステートメント属性SQL_ATTR_USE_BOOKMARKSは、列を列 0 にバインドする前に常に設定する必要があります。 これは必須ではありませんが、強くお勧めします。
バインディング列
列をバインドするために、アプリケーションは SQLBindCol を 呼び出し、データ バッファーの列番号、型、アドレス、長さ、および長さ/インジケーター バッファーのアドレスを渡します。 これらのアドレスの使用方法については、このセクションで後述する「バッファー アドレス」を参照してください。 列のバインドの詳細については、「 SQLBindCol の使用」を参照してください。
これらのバッファーの使用は遅延されます。つまり、アプリケーションは SQLBindCol でバインドしますが、ドライバーは他の関数 (SQLBulkOperations、SQLFetch、SQLFetchScroll、または SQLSetPos) からアクセスします。 SQLBindCol で指定されたポインターが有効なままである限り、バインドが有効なままであることを確認するのは、アプリケーションの責任です。 アプリケーションでこれらのポインターが無効になることを許可した場合 (たとえば、バッファーを解放し、有効であると想定する関数を呼び出すと、結果は未定義になります)。 詳細については、「 遅延バッファー」を参照してください。
バインドは、新しいバインドに置き換えられるか、列がバインドされていないか、ステートメントが解放されるまで有効なままです。
列のバインド解除
1 つの列のバインドを解除するために、アプリケーションは、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 つの行の データが含まれているため、これは行方向バインドと呼ばれます。
バッファーの各配列には、少なくとも行セットのサイズと同じ数の要素が必要です。
Note
アプリケーションでは、配置が有効であることを確認する必要があります。 配置に関する考慮事項の詳細については、「 配置」を参照してください。
列方向のバインド
列ごとのバインドでは、アプリケーションは個別のデータ配列と長さ/インジケーター配列を各列にバインドします。
列方向バインドを使用するために、アプリケーションは最初に SQL_ATTR_ROW_BIND_TYPE ステートメント属性を SQL_BIND_BY_COLUMN に設定します。 (これが既定値です)。バインドする列ごとに、アプリケーションは次の手順を実行します。
データ バッファー配列を割り当てます。
長さ/インジケーター バッファーの配列を割り当てます。
Note
列方向のバインドを使用するときにアプリケーションが記述子に直接書き込む場合は、長さとインジケーター データに個別の配列を使用できます。
次の引数を使用して SQLBindCol を呼び出します。
TargetType は、データ バッファー配列内の 1 つの要素の型です。
TargetValuePtr は、データ バッファー配列のアドレスです。
BufferLength は、データ バッファー配列内の 1 つの要素のサイズです。 BufferLength 引数は、データが固定長データの場合は無視されます。
StrLen_or_IndPtr は、長さ/インジケーター配列のアドレスです。
この情報の使用方法の詳細については、このセクションで後述する「バッファー アドレス」を参照してください。 列方向のバインドの詳細については、「 列方向のバインド」を参照してください。
行方向のバインド
行方向バインディングでは、バインドする各列のデータバッファーと長さ/インジケーター バッファーを含む構造体がアプリケーションによって定義されます。
行方向バインドを使用するには、アプリケーションで次の手順を実行します。
1 行のデータ (データバッファーと長さ/インジケーター バッファーの両方を含む) を保持する構造体を定義し、これらの構造体の配列を割り当てます。
Note
行方向のバインドを使用するときにアプリケーションが記述子に直接書き込む場合は、長さとインジケーター データに個別のフィールドを使用できます。
SQL_ATTR_ROW_BIND_TYPE ステートメント属性を、単一のデータ行を含む構造体のサイズ、または結果列をバインドするバッファーのインスタンスのサイズに設定します。 バインドされた列のアドレスが指定した長さでインクリメントされると、結果が次の行の同じ列の先頭を指すようにするには、長さにすべてのバインドされた列のスペースと構造体またはバッファーの埋め込みを含める必要があります。 ANSI C で sizeof 演算子を使用する場合、この動作は保証されます。
バインドする各列に対して、次の引数を指定して SQLBindCol を呼び出します。
TargetType は、列にバインドされるデータ バッファー メンバーの型です。
TargetValuePtr は、最初の配列要素のデータ バッファー メンバーのアドレスです。
BufferLength は、データ バッファー メンバーのサイズです。
StrLen_or_IndPtr は、バインドする長さ/インジケーター メンバーのアドレスです。
この情報の使用方法の詳細については、このセクションで後述する「バッファー アドレス」を参照してください。 列方向のバインドの詳細については、「 行方向のバインド」を参照してください。
バッファー アドレス
バッファー アドレスは、データまたは長さ/インジケーター バッファーの実際のアドレスです。 ドライバーは、バッファーに書き込む直前 (フェッチ時など) にバッファー アドレスを計算します。 次の数式から計算されます。 TargetValuePtr 引数と StrLen_or_IndPtr 引数で指定されたアドレス、バインド オフセット、行番号を使用します。
バインドされたアドレス + バインディング オフセット + ((行番号 - 1) x 要素サイズ)
ここで、数式の変数は、次の表で説明するように定義されています。
変数 | 説明 |
---|---|
バインドされたアドレス | データ バッファーの場合、SQLBindCol で TargetValuePtr 引数で指定されたアドレス。 長さ/インジケーター バッファーの場合、SQLBindCol でStrLen_or_IndPtr引数で指定されたアドレス。 詳細については、「Descriptors and 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) です。 データ バッファーの場合、データ型が可変長の場合は SQLBindCol の BufferLength 引数の値、データ型が固定長の場合はデータ型のサイズです。 行方向のバインドを使用する場合、これはデータ バッファーと長さ/インジケーター バッファーの両方のSQL_ATTR_ROW_BIND_TYPE ステートメント属性の値です。 |
記述子と SQLBindCol
次のセクションでは、 SQLBindCol が 記述子と対話する方法について説明します。
注意事項
1 つのステートメントに対して SQLBindCol を 呼び出すと、他のステートメントに影響を与える可能性があります。 これは、ステートメントに関連付けられている ARD が明示的に割り当てられ、他のステートメントにも関連付けられている場合に発生します。 SQLBindCol は記述子を変更するため、この記述子が関連付けられているすべてのステートメントに変更が適用されます。 これが必要な動作でない場合、アプリケーションは SQLBindCol を呼び出す前に、他のステートメントからこの記述子の関連付けを解除する必要があります。
引数マッピング
概念的には、 SQLBindCol は 次の手順を順番に実行します。
SQLGetStmtAttr を呼び出して ARD ハンドルを取得します。
SQLGetDescField を呼び出してこの記述子のSQL_DESC_COUNT フィールドを取得し、ColumnNumber 引数の値が SQL_DESC_COUNT の値を超える場合は、SQLSetDescField を呼び出して、SQL_DESC_COUNTの値を ColumnNumber に増やします。
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 を指定すると、アプリケーションの誤解が簡単に検出されます。 ただし、アプリケーションで TargetType に SQL_DEFAULTが指定されている場合、 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 関数 |