仕様: | DB2 CLI 1.1 | ODBC 1.0 | ISO CLI |
SQLBindCol() は、次のどちらかに結果セット内の列を関連付ける (バインドする) ために使用します。
別の方法として、 SQLBindFileToCol() を使用して LOB 列をファイルに直接バインドすることができます。
SQLBindCol() は、アプリケーションが取り出す必要のある結果セット中の列ごとに 1 回呼び出されます。
一般に、SQLPrepare()、 SQLExecDirect() またはスキーマ関数の 1 つがこの関数の前に呼び出され、その後で SQLFetch() または SQLFetchScroll() が呼び出されます。 SQLBindCol() を呼び出す前に列属性も必要となる場合があり、 SQLDescribeCol() または SQLColAttribute() を使用して取得することができます。
構文
SQLRETURN SQLBindCol (SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, SQLPOINTER TargetValuePtr, SQLINTEGER BufferLength, SQLINTEGER *FAR StrLen_or_IndPtr);
関数引き数
データ・タイプ | 引き数 | 使用法 | 説明 |
---|---|---|---|
SQLHSTMT | StatementHandle | 入力 | ステートメント・ハンドル |
SQLUSMALLINT | ColumnNumber | 入力 | 列を識別する番号。列は、左から右へ順番に番号が付けられています。
|
SQLSMALLINT | TargetType | 入力 | 結果セット内の列番号 ColumnNumber 用の C データ・タイプ。以下のタイプがサポートされます。
SQL_C_DEFAULT を指定するとデータが省略時の C データ・タイプに転送されます。詳細については表 2 を参照してください。 |
SQLPOINTER | TargetValuePtr | 入出力 (据え置き) | 取り出しが起きたときに、
DB2 CLI が列データまたは LOB ロケーターを保管するバッファー (または SQLFetchScroll() を使用する場合はバッファーの配列) を指すポインター。
SQLSetPos に対する Operation 引き数が SQL_REFRESH のときに、このバッファーを使用してデータが返されます。 SQLSetPos の Operation 引き数が SQL_UPDATE に設定されているときに、このバッファーを使用してデータが取り出されます。
TargetValuePtr がヌルの場合は、列はアンバインドされます。 |
SQLINTEGER | BufferLength | 入力 | 列データまたは LOB ロケーターを保管するために使用可能な TargetValuePtr バッファーのサイズ (バイト)。
TargetType が 2 進または文字ストリング (単一バイトまたは 2 バイト) を表す場合、あるいは TargetType が SQL_C_DEFAULT である場合は、 BufferLength が 0 より大きくなければならず、そうでないとエラーが返されます。それ以外の場合は、この引き数は無視されます。 |
SQLINTEGER * | StrLen_or_IndPtr | 入出力 (据え置き) | DB2 CLI が TargetValuePtr バッファー内に返すために使用できるバイト数を示す値 (または値の配列) を指すポインター。
TargetType が LOB ロケーターの場合は、
LOB データのサイズではなくロケーターのサイズが返されます。
SQLSetPos に対する Operation 引き数が SQL_REFRESH のときに、このバッファーを使用してデータが返されます。 SQLSetPos の Operation 引き数が SQL_UPDATE に設定されているときに、このバッファーを使用してデータが取り出されます。
列のデータ値が NULL の場合は、 SQLFetch() はこの引き数に SQL_NULL_DATA を返します。
このポインターの値は、バインドされた列ごとに固有であるか、または NULL でなければなりません。
SQL_COLUMN_IGNORE の値は、 SQLBulkOperations() と共に使用するために設定することもできます。詳細については、SQLBulkOperations - 行のセットの追加、更新、削除、または取り出しを参照してください。
SQL_NO_LENGTH が返されることもあります。詳細については、後述の使用法の項を参照してください。 |
使用法
アプリケーションは、データまたは (LOB 列の場合は任意選択で) LOB ロケーターのどちらかを検索するために必要な結果セット内の列ごとに 1 回ずつ SQLBindCol() を呼び出します。結果セットは、 SQLExecute()、 SQLExecDirect()、 SQLGetTypeInfo()、またはカタログ関数のいずれかを呼び出すと生成されます。 SQLFetch() を呼び出すときは、そのバインドされた 列のそれぞれにあるデータは、割り当てた場所に置かれます (ポインター TargetValuePtr および StrLen_or_Ind で指される場所に)。 TargetType が LOB ロケーターの場合は、LOB データではなくロケーター値が返されます。 LOB ロケーターは LOB 列内のすべてのデータ値を参照します。
SQLFetch() および SQLFetchScroll() を使用すると、結果セットから複数行を配列内に取り出すことができます。この場合、TargetValuePtr は配列を参照します。詳細については、配列への結果セットの取り出しおよび SQLFetchScroll - バインド列すべての行セットを取り出し、データを返すを参照してください。
列は、左から右へ順番に割り当てられた番号で識別されます。
ブックマークを使用しようとする場合は、最初に SQL_ATTR_USE_BOOKMARKS ステートメント属性を SQL_UB_ON に設定しなければなりません。
結果セットの列番号を判別するには、DescType 引き数を SQL_COLUMN_COUNT に設定して SQLNumResultCols() または SQLColAttribute() を呼び出します。
アプリケーションは、最初に SQLDescribeCol() または SQLColAttribute() を呼び出すと、列の属性 (データ・タイプやデータ長など) を照会することができます。次にこの情報を使用して正しいデータ・タイプと長さで記憶場所を割り振って、別のデータ・タイプへのデータ変換を指示するか、 LOB データ・タイプの場合にロケーターを返すこともできます。省略時のタイプとサポートされる変換の詳細については、 データ・タイプとデータ変換を参照してください。
アプリケーションは、すべての列をバインドするとは限らないことを選択したり、またはどの列もバインドしないことを選択することもできます。また、どの列にあるデータでも、バインドされている列を現在行のために取り出してから、SQLGetData() を使用して取り出すことができます。一般には、 SQLBindCol() の方が SQLGetData() よりも効果的です。ある関数を別の関数に優先して使用すべき時についての説明は、 付録 A, プログラミングのヒントと提案を参照してください。
これ以降の取り出しで、アプリケーションは SQLBindCol() を呼び出して、これらの列の結び付きを変更したり、すでにアンバインドされている列をバインドすることができます。新規のバインドは、すでに取り出したデータには適用されず、次回の取り出しから使用されます。単一の列 (SQLBindFileToCol() を使用してバインドされている列を含む) をアンバインドするには、 NULL に設定した TargetValuePtr ポインターを用いて SQLBindCol() を呼び出します。すべての列をアンバインドするには、アプリケーションは、 SQL_UNBIND に設定してある Option 入力を用いて SQLFreeStmt() を呼び出します。
SQLBindCol() への複数の呼び出しの代わりに、 DB2 CLI はパラメーター・バインドの相対位置もサポートしています。毎回再バインドするよりも、相対位置を使用すると、SQLFetch() または SQLFetchScroll() への次回の呼び出しで使用される新しいバッファー・アドレスおよび長さ / 標識アドレスを指定することができます。これは、行方向バインドでのみ使用できますが、アプリケーションが一度に単一行を取り出すか、または複数行を取り出すかを決めます。
相対位置を使用するのに必要なステップのリストについては、 列バインドの相対位置を参照してください。
アプリケーションは、取り出されるデータのために十分な記憶域が割り振られていることを確認する必要があります。バッファーに可変長のデータを入れる場合、アプリケーションは最大長のバインドされた列が必要とする記憶域を割り当てる必要があります。そうしないと、データが切り捨てられることがあります。バッファーに固定長データを入れる場合、 DB2 CLI はバッファーのサイズを C データ・タイプの長さと想定します。データ変換を指定すると、必須サイズが変わる場合があります。詳細については、データ・タイプとデータ変換を参照してください。
ストリングの切り捨てが起きた場合、SQL_SUCCESS_WITH_INFO が返されて、StrLen_or_IndPtr が、アプリケーションへの戻りに使用可能な実際のサイズの TargetValuePtr に設定されます。
切り捨ても SQL_ATTR_MAX_LENGTH ステートメント属性によって影響を受けます (そのステートメント属性はアプリケーションへ返されるデータ量を制限するために使用されます)。アプリケーションは、 SQL_ATTR_MAX_LENGTH とすべての可変長列に返される最大長の値を使用して SQLSetStmtAttr() を呼び出し、さらに、同じサイズ (ヌル終止符を足す) の TargetValuePtr バッファーを割り振ることによって、切り捨てを報告しないように指定することができます。列データが設定された最大長より大きい場合、値が取り出されたときに SQL_SUCCESS が返されますが、実際の長さではなく最大長が StrLen_or_IndPtr に返されます。
バインドされる列が SQL_GRAPHIC、SQL_VARGRAPHIC、または SQL_LONGVARGRAPHIC のタイプである場合は、TargetType を SQL_C_DBCHAR または SQL_C_CHAR に設定することができます。 TargetType が SQL_C_DBCHAR である場合は、 TargetValuePtr バッファーに取り出されるデータは、 2 バイトのヌル終止符でヌル終了します。 TargetType が SQL_C_CHAR である場合は、データのヌル終了はありません。いずれの場合も、TargetValuePtr バッファーの長さ (BufferLength) はバイト単位であり、そのため 2 の倍数になります。強制的に DB2 CLI に図形ストリングをヌル終了させることもできます。 構成キーワードの PATCH1 キーワードを参照してください。
注: | SQL_NO_TOTAL は、次の場合に StrLen_or_IndPtr に返されます。 |
LOB ロケーターは、一般に他の任意のデータ・タイプとして処理できますが、次のような重要な相違点があります。
LOB ロケーターは、データベース位置を指すポインターではなく、 LOB 値への参照、つまり LOB 値のスナップショットです。カーソルの現在位置と LOB 値が抽出された行との間には、何の関連もありません。このことは、カーソルが異なる行へ移動した後でも、 LOB ロケーター (および LOB ロケーターが表す値) が、まだ参照できることを意味します。
結果セット内の特定の LOB 列の場合、以下の対象をバインドすることができます。
最新の列バインド関数呼び出しは、有効なバインドのタイプを判別します。
記述子および SQLBindCol
以下の項では、SQLBindCol() が記述子と対話する方法について説明します。
注: | 1 つのステートメントに SQLBindCol() 呼び出しを行うと、他のステートメントにも影響します。それが生じるのは、ステートメントに関連した ARD が明示的に割り当てられ、それらが他のステートメントにも関連しているような場合です。 SQLBindCol() は記述子を変更するので、そのような変更は、この記述子が関連しているすべてのステートメントに適用されます。これが必要な動作でない場合、アプリケーションは、 SQLBindCol() を呼び出す前に、他のステートメントから関連付けを解除する必要があります。 |
引き数のマッピング
概念的には、SQLBindCol() は、以下のステップを順次実行します。
StrLen_or_Ind 引き数が参照する変数は、標識および長さの情報のために使用されます。取り出しがその列についてヌル値を検出した場合は、この変数に SQL_NULL_DATA を保管し、そうでなければ、この変数にデータ長を保管します。 NULL ポインターを StrLen_or_Ind として渡せば、取り出し操作でデータ長を返さないようにできますが、ヌル値を検出した場合に取り出しを失敗させてしまうと、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() は、メタデータへの変更か、異なる列へのコードの適用のどちらかの方法により、アプリケーションが意図した列から、異なるデータ・タイプの列へと適用することができます。この場合、アプリケーションは、取り出す列データの開始または長さを判別するのに失敗する可能性があります。このことで、報告されないデータ・エラーまたはメモリー違反が起きることがあります。
戻りコード
診断
SQLSTATE | 説明 | 解説 | ||
---|---|---|---|---|
07009 | 無効な記述子索引 | 引き数 ColumnNumber に指定された値が、結果セット内の列の最大数を超えました。 | ||
40003 08S01 | 通信リンクに障害が起きました。 | アプリケーションとデータ・ソースとの間の通信リンクが、関数の完了する前に失敗しました。 | ||
58004 | 予期しないシステム障害です。 | 回復不能システム・エラー。 | ||
HY001 | メモリーの割り振り失敗です。 | DB2 CLI は、関数の実行または完了をサポートするのに必要なメモリーを割り振ることができません。 | ||
HY002 | 列の番号が無効です。 | 引き数 ColumnNumber に指定された値は、0 より小さい値でした。
引き数 ColumnNumber に指定された値が、データ・ソースでサポートされる列の最大数を超えました。 | ||
HY003 | プログラム・タイプが範囲外です。 | TargetType は、有効なデータ・タイプまたは SQL_C_DEFAULT ではありませんでした。 | ||
HY010 | 関数の順序エラーです。 | 実行時データ (SQLParamData()、
SQLPutData()) 操作中に、関数が呼び出されました。
BEGIN COMPOUND と END COMPOUND SQL の操作中に、関数が呼び出されました。 | ||
HY013 | 予期しないメモリーのハンドル・エラーが起きました。 | DB2 CLI は、関数の実行または完了をサポートするのに必要なメモリーを使用することができませんでした。 | ||
HY090 | ストリングまたはバッファー長が無効です。 | 引き数 BufferLength に指定された値は 1 より小さく、引き数 TargetType は SQL_C_CHAR、 SQL_C_BINARY、または SQL_C_DEFAULT のいずれかです。 | ||
HYC00 | ドライバーが機能していません。 | DB2 CLI は引き数 TargetType に指定されているデータ・タイプを認識はしますが、サポートしません。
LOB ロケーター C データ・タイプが指定されましたが、接続されているサーバーは LOB データ・タイプをサポートしていません。 | ||
|
制約
LOB データ・サポートは、ラージ・オブジェクト・データ・タイプをサポートするサーバーに接続しているときしか使用できません。アプリケーションが LOB ロケーター C データ・タイプを指定しようとする場合、 SQLSTATE HYC00 が返されます。
(ここで完全サンプル utilcli.c を使用することもできます 。)
/* From the CLI sample utilcli.c */ /* ... */ /* bind columns to program vars, converting all types to CHAR */ sqlrc = SQLBindCol( hstmt, ( SQLSMALLINT ) ( i + 1 ), SQL_C_CHAR, outData[i].buff, outData[i].buffLen, &outData[i].len ) ; STMT_HANDLE_CHECK( hstmt, sqlrc);
参照