仕様: | DB2 CLI 1.1 | ODBC 1.0 | ISO CLI |
SQLFetch() は結果セットの次の行へカーソルを進ませ、バインドされた列を取り出します。
列を次の位置にバインドすることができます。
SQLFetch() を呼び出すと、適切なデータ転送が行われるとともに、列がバインドされたときに変換が指示されているとデータ変換が行われます。 SQLGetData() を呼び出して、取り出しの後に列を個々に受け取ることもできます。
SQLFetch() は、照会を実行するか、 SQLGetTypeInfo() 関数を呼び出すか、またはカタログ関数を呼び出すかのいずれかにより、結果セットを生成した後にのみ (同一ステートメント・ハンドルを使用して) 呼び出すことができます。
一度に複数行を取り出すには、SQLFetchScroll() を使用します。
構文
SQLRETURN SQLFetch (SQLHSTMT StatementHandle); /* hstmt */
関数引き数
データ・タイプ | 引き数 | 使用法 | 説明 |
---|---|---|---|
SQLHSTMT | StatementHandle | 入力 | ステートメント・ハンドル |
使用法
SQLFetch() は、同じステートメント・ハンドルで結果セットが生成された後にのみ呼び出すことができます。 SQLFetch() を初めて呼び出す前には、カーソルを結果セットの先頭の前に置きます。
SQLBindCol() でバインドされたアプリケーション変数の個数が結果セット内の列数を超えてはなりません。超えると、SQLFetch() が失敗します。
SQLBindCol() を呼び出して列をバインドしなかった場合、 SQLFetch() はアプリケーションにデータを返さず、カーソルを進ませることだけ行います。この場合、SQLGetData() を呼び出して、すべての列を個々に取得することができます。カーソルが複数行カーソルの場合 (つまり、SQL_ATTR_ROW_ARRAY_SIZE が 1 より大きい場合)、 SQL_GETDATA_EXTENSIONS の InfoType を使用して SQLGetInfo() を呼び出すときに SQL_GD_BLOCK が返された場合にのみ、 SQLGetData() を呼び出すことができます。 SQLFetch() でカーソルを次の行に進ませると、アンバインドされた列のデータが廃棄されます。固定長データ・タイプまたは小さい可変長データ・タイプの場合、 SQLGetData() を使用して列をバインドすることにより、より良いパフォーマンスが得られます。
列を以下の位置にバインドすることができます。
SQLBindCol() は、アプリケーション記憶域を列にバインドするときに使用します。データは、取り出し時にサーバーからアプリケーションへ転送されます。返すために利用できるデータの長さも設定できます。
SQLBindCol() は、LOB ロケーターを列にバインドするときに使用します。取り出し時には、サーバーからアプリケーションへ LOB ロケーター (4 バイト) だけが転送されます。
一度アプリケーションがロケーターを受け取ると、それを SQLGetSubString()、 SQLGetPosition()、SQLGetLength() に使用したり、別の SQL ステートメントのパラメーター・マーカーの値として使用することができます。 SQLGetSubString() は、別のロケーターか、またはデータ自体を返すことができます。すべてのロケーターは、そのロケーターを作成したトランザクションの終了まで (カーソルが別の行へ移動した場合も含む)、または FREE LOCATOR ステートメントでロケーターが解放されるまで有効です。
SQLBindFileToCol() は、ファイルを LOB 列にバインドするときに使用します。 DB2 CLI はデータを直接ファイルに書き込み、 SQLBindFileToCol() に指定された StringLength および IndicatorValue バッファーを更新します。
列のデータ値が NULL で、SQLBindCol() が使用されている場合、 SQL_NULL_DATA は SQLBindCol() に指定されている pcbValue バッファーに保管されます。
列のデータ値が NULL で、SQLBindFileToCol() が使用されている場合、 IndicatorValue は SQL_NULL_DATA に設定され、 StringLength は 0 に設定されます。
LOB 値が大きすぎて 1 回の取り出しで検索できない場合、 SQLGetData() (どの列タイプにも使用可能) を使用するか、または LOB ロケーターをバインドして SQLGetSubString() を使用することにより、 LOB 値を部分単位で検索することができます。
バインドされた記憶域バッファーが、 SQLFetch() から返されたデータを保持するほど大きくないと、データは切り捨てられます。文字データが切り捨てられると、SQL_SUCCESS_WITH_INFO が返され、切り捨てを示す SQLSTATE が生成されます。 SQLBindCol() 据え置き出力引き数 pcbValue には、サーバーから取り出される列データの実際の長さが含まれます。アプリケーションは、実際の出力の長さを入力バッファーの長さ (SQLBindCol() からの pcbValue 引き数と cbValueMax 引き数) と比較して、どの文字列が切り捨てられたかを判別する必要があります。
切り捨てが小数点の右側の桁数に関係している場合、数値データ・タイプの切り捨ては警告として報告されます。切り捨てが小数点の左側で行われると、エラーが返されます (診断のセクションを参照)。
図形データ・タイプの切り捨ては文字データ・タイプと同じ方法で処理されます。ただし、rgbValue バッファーが、 SQLBindCol() で指定されている cbValueMax の値以下の最も大きい 2 バイトの倍数まで埋め込まれるという点だけが異なります。 DB2 CLI とアプリケーションとの間で転送された図形 (DBCS) データは、 C バッファー・タイプが SQL_C_CHAR のときにはヌル終了しません。 (ただし、PATCH1 初期設定キーワードによる指定がない場合です。詳細については、構成キーワードを参照してください。) バッファー・タイプが SQL_C_DBCHAR の場合は、図形データはヌル終了します。
切り捨ては、SQL_ATTR_MAX_LENGTH ステートメント属性にも影響されます。アプリケーションは、 SQL_ATTR_MAX_LENGTH および列ごとに返される最大長の値を指定して SQLSetStmtAttr() を呼び出し、同サイズ (にヌル終止符を加えたもの) の rgbValue バッファーを割り振ることによって、 DB2 CLI が切り捨てを報告しないように指定することができます。列データが設定された最大長より大きい場合、SQL_SUCCESS が返され、実際の長さでなく最大長が pcbValue に返されます。
結果セットからすべての行を取り出した場合か、残りの行が不要である場合、 SQLFreeStmt() を呼び出し、カーソルをクローズして残りのデータと関連資源を廃棄する必要があります。
一度に複数行を取り出すには、SQLFetchScroll() を使用します。アプリケーションは、同じステートメント・ハンドルで SQLFetch() 呼び出しと SQLExtendedFetch() 呼び出しを混合できません。しかし、同じステートメント・ハンドルで SQLFetch() 呼び出しと SQLFetchScroll() 呼び出しを混合することはできます。
カーソルの位置決め
結果セットが作成されたら、カーソルは結果セットの先頭の前に置かれます。 SQLFetch() は次の行セットを取り出します。 FetchOrientation セットを使用する SQLFetchScroll() の呼び出しは、 SQL_FETCH_NEXT と同等です。詳細については、スクロール可能カーソルを参照してください。
SQL_ATTR_ROW_ARRAY_SIZE ステートメント属性は、行セット内の行数を指定します。 SQLFetch() によって取り出されている行セットが結果セットの最後とオーバーラップする場合、 SQLFetch() は行セットの一部を返します。つまり、S + R-1 が L より大きい場合、(この S は取り出されている行セットの開始行、 R は行セット・サイズ、L は結果セットの最後の行)、行セットの最初の L-S+1 行のみが有効になります。残りの行は空であり、状況は SQL_ROW_NOROW になります。
詳細については、 SQL_FETCH_NEXT の SQLFetchScroll()、『カーソル位置の規則』を参照してください。
SQLFetch() が返された後では、現在行は行セットの最初の行になります。
行状況の配列
SQLFetch() は SQLFetchScroll() と同じ方法で行状況配列の値を設定します。詳しくは、SQLFetchScroll()、 『行状況』を参照してください。
行フェッチ・バッファー
SQLFetch() は、 SQLFetchScroll() と同じ方法で行フェッチ・バッファーに取り出されている行の数を返します。詳しくは、SQLFetchScroll()、『行フェッチ・バッファー』を参照してください。
エラーと警告は、個々の行、または関数全体に対して提供されます。診断レコードの詳細については、SQLGetDiagField - 診断データのフィールドの入手を参照してください。
関数全体についてのエラーおよび警告
エラーが、関数全体に適用される場合、たとえば SQLSTATE HYT00 (タイムアウト満了)、または SQLSTATE 24000 (カーソル状況が無効) の場合、SQLFetch() は SQL_ERROR と、適用可能な SQLSTATE を返します。行セット・バッファーの内容は定義されず、カーソル位置は変更されません。
警告が関数全体に当てはまる場合、 SQLFetch() は SQL_SUCCESS_WITH_INFO と適用可能な SQLSTATE を返します。関数全体に適用される警告の状況レコードは、個々の行に適用される状況レコードよりも前に返されます。
個々の行のエラーおよび警告
エラー (SQLSTATE 22012 (ゼロによる除算) または警告 SQLSTATE 01004 (データが切り捨てられた)) は、単一行、SQLFetch() に適用されます。
SQLFetch() は、行セットにある行をすべて取り出すまで、行の取り出しを継続します。行セットの各行 (状況が SQL_ROW_NOROW である行はカウントしない) でエラーが生じない限り、 SQL_SUCCESS_WITH_INFO が返されます。エラーが生じた場合は、SQL_ERROR が返されます。特に、行セットのサイズが 1 であり、その行でエラーが生じると、 SQLFetch() は SQL_ERROR を返します。
SQLFetch() は行番号の順に状況レコードを返します。つまり、認識されていない行 (存在する場合) の状況レコードをすべて返してから、最初の行 (存在する場合) の状況レコードをすべて返し、その後、 2 番目の行 (存在する場合) の状況レコードを返す、という具合に続きます。それぞれの行の状況レコードは、通常の状況レコードの配列規則に基づいて配列されます。詳細については、SQLGetDiagField()、『状況レコードの順序』を参照してください。
以下のセクションでは、SQLFetch() が記述子と対話する方法について説明します。
引き数のマッピング
ドライバーは、引き数 SQLFetch() に基づいて記述子フィールドを設定することはありません。
他の記述子フィールド
以下の記述子フィールドは、SQLFetch() によって使用されます。
記述子フィールド | 説明 | 位置 | 設定時に使用するもの |
---|---|---|---|
SQL_DESC_ARRAY_SIZE | ARD | ヘッダー | SQL_ATTR_ROW_ARRAY_SIZE ステートメント属性 |
SQL_DESC_ARRAY_STATUS_PTR | IRD | ヘッダー | SQL_ATTR_ROW_STATUS_PTR ステートメント属性 |
SQL_DESC_BIND_OFFSET_PTR | ARD | ヘッダー | SQL_ATTR_ROW_BIND_OFFSET_PTR ステートメント属性 |
SQL_DESC_BIND_TYPE | ARD | ヘッダー | SQL_ATTR_ROW_BIND_TYPE ステートメント属性 |
SQL_DESC_COUNT | ARD | ヘッダー | SQLBindCol() の ColumnNumber 引き数 |
SQL_DESC_DATA_PTR | ARD | レコード | SQLBindCol() の TargetValuePtr 引き数 |
SQL_DESC_INDICATOR_PTR | ARD | レコード | SQLBindCol() の StrLen_or_IndPtr 引き数 |
SQL_DESC_OCTET_LENGTH | ARD | レコード | SQLBindCol() の BufferLength 引き数 |
SQL_DESC_OCTET_LENGTH_PTR | ARD | レコード | SQLBindCol() の StrLen_or_IndPtr 引き数 |
SQL_DESC_ROWS_PROCESSED_PTR | IRD | ヘッダー | SQL_ATTR_ROWS_FETCHED_PTR ステートメント属性 |
SQL_DESC_TYPE | ARD | レコード | SQLBindCol() の TargetType 引き数 |
すべての記述子フィールドは SQLSetDescField() を介して設定することもできます。
長さおよび標識バッファーの分離
アプリケーションは、単一のバッファーまたは 2 つの別個のバッファーを使用して長さおよび標識値を保持することができます。アプリケーションが SQLBindCol() を呼び出すときに、 ARD の SQL_DESC_OCTET_LENGTH_PTR と SQL_DESC_INDICATOR_PTR フィールドは同一のアドレスに設定されます。これは、StrLen_or_IndPtr 引き数に渡されます。アプリケーションが SQLSetDescField() または SQLSetDescRec() を呼び出すときに、これらの 2 つのフィールドを異なるアドレスに設定することができます。
SQLFetch() は、アプリケーションが別々の長さおよび標識バッファーを指定したかどうかを判別します。この場合にデータが NULL でないなら、SQLFetch() は標識バッファーを 0 に設定し、長さバッファーに長さを返します。データが NULL である場合、SQLFetch() は標識バッファーを SQL_NULL_DATA に設定し、長さバッファーは修正しません。
戻りコード
結果セット内に行がない場合、または直前の SQLFetch() 呼び出しで結果セットからすべての行が取り出された場合、 SQL_NO_DATA_FOUND が返されます。
すべての行が取り出された場合、カーソルは結果表の末尾の後ろに置かれます。
診断
SQLSTATE | 説明 | 解説 | ||
---|---|---|---|---|
07009 | 無効な記述子索引 | 列 0 がバインドされましたが、ブックマークが使用されませんでした (SQL_ATTR_USE_BOOKMARKS ステートメントが SQL_UB_OFF に設定されました)。 | ||
01004 | データが切り捨てられました。 | 1 つまたは複数の列について返されたデータが切り捨てられました。ストリング値または数値は右方切り捨てされます。 (エラーが発生しなかった場合、SQL_SUCCESS_WITH_INFO が返されます。) | ||
07002 | 列が多すぎます。 | バインド中に指定された 1 つまたは複数の列の列番号が、結果セット内の列数より大きい値でした。 | ||
07006 | 変換が無効です。 | データ値を、 SQLBindCol() の fCType で指定されたデータ・タイプに有意義な方法で変換できませんでした。 | ||
22002 | 無効な出力または標識バッファーが指定されました。 | SQLBindCol() の引き数 pcbValue に指定されたポインター値はヌル・ポインターでしたが、対応する列の値はヌルです。 SQL_NULL_DATA を報告する手段はありません。 SQLBindFileToCol() の引き数 IndicatorValue に指定されたポインターはヌル・ポインターでしたが、対応する LOB 列は NULL です。 SQL_NULL_DATA を報告する手段はありません。 | ||
22003 | 数値が範囲外です。 | 1 つまたは複数の列の数値を (数値またはストリングとして) 返したため、割り当て時または中間結果の計算時に数値の整数部分が切り捨てられたと考えられます。
ゼロでの除算が行われた算術式からの値が返されました。
| ||
22005 | 割り当てにエラーがありました。 | 返された値は、バインドのデータ・タイプと互換性がありませんでした。
返された LOB ロケーター値は、バインドされた列のデータ・タイプと互換性がありませんでした。 | ||
22007 | 日時形式が無効です。 | 文字ストリングから日時形式への変換が指定されましたが、無効なストリング表示または値が指定されたか、あるいは値が無効な日付になっています。
日付、時刻、またはタイム・スタンプの値が、指定された日付タイプの構文に従っていません。 | ||
22008 | 日時フィールドがオーバーフローしました。 | 日時フィールドがオーバーフローしました。たとえば、日付またはタイム・スタンプの算術計算の結果が有効な日付範囲内にないか、または日時の値が小さ過ぎて、結合変数に割り当てることができません。 | ||
22012 | ゼロによる割算は無効です。 | ゼロでの除算が行われた算術式からの値が返されました。 | ||
24000 | カーソル状態が無効です。 | ステートメント・ハンドルで実行された直前の SQL ステートメントは照会ではありませんでした。 | ||
40003 08S01 | 通信リンクに障害が起きました。 | アプリケーションとデータ・ソースとの間の通信リンクが、関数の完了する前に失敗しました。 | ||
428A1 | ホスト・ファイル変数で参照されるファイルにアクセスできません。 | これは、以下のシナリオで生ずる可能性があります。テキスト内で関連付けられた理由コードは、特定のエラーを表します。
| ||
54028 | 並行 LOB ハンドルが最大数に達しました。 | 割り当てられた最大 LOB ロケーター。
並行 LOB ロケーターの最大数に達しました。新しいロケーターを割り当てることができません。 | ||
56084 | DRDA では、LOB データはサポートされていません。 | LOB が DRDA でサポートされていません。
DRDA サーバーに接続 (DB2 コネクトを使用して行う) しているときには、 LOB 列の選択や更新を行うことができません。 | ||
58004 | 予期しないシステム障害です。 | 回復不能システム・エラー。 | ||
HY001 | メモリーの割り振り失敗です。 | DB2 CLI は、関数の実行または完了をサポートするのに必要なメモリーを割り振ることができません。 | ||
HY008 | 操作が取り消しになりました。 |
非同期処理が StatementHandle に対して使用可能になりました。関数が呼び出され、その実行が完了する前に、 SQLCancel() が StatementHandle で呼び出されました。そして、関数が再び StatementHandle で呼び出されました。 関数が呼び出され、その実行が完了する前に、
SQLCancel() が複数スレッドのアプリケーション内の別のスレッドから、
StatementHandle で呼び出されました。
| ||
HY010 | 関数の順序エラーです。 | SQLExtendedFetch() を呼び出した後、
SQL_CLOSE オプションを指定して SQLFreeStmt() を呼び出す前に、
StatementHandle の SQLFetch() を呼び出しました。
StatementHandle の SQLPrepare() または SQLExecDirect() を呼び出す前に、この関数を呼び出しました。
実行時データ (SQLParamData()、 SQLPutData()) 操作中に、関数が呼び出されました。
BEGIN COMPOUND と END COMPOUND SQL の操作中に、関数が呼び出されました。 | ||
HY013 | 予期しないメモリーのハンドル・エラーが起きました。 | DB2 CLI は、関数の実行または完了をサポートするのに必要なメモリーを使用することができませんでした。 | ||
HY092 | オプション・タイプが範囲外です。 | 直前の SQLBindFileToCol() 操作の FileOptions 引き数が無効でした。 | ||
HYC00 | ドライバーが機能していません。 | DB2 CLI またはデータ・ソースは、
SQLBindCol() または SQLBindFileToCol() の fCType および対応する列の SQL データ・タイプの組み合わせによって指定された変換をサポートしません。
DB2 CLI によってサポートされていない列データ・タイプに対して、 SQLBindCol() 呼び出しが行われました。 | ||
HYT00 | タイムアウトになりました。 | データ・ソースが結果セットを返す前に、タイムアウト期間が満了しました。タイムアウトは、 Windows 3.1 や Macintosh System 7 のようなマルチタスクではないシステム上でのみサポートされています。タイムアウト期間は、 SQLSetConnectAttr() の SQL_ATTR_QUERY_TIMEOUT 属性を使用して設定することができます。 |
制約
なし。
(ここで完全サンプル utilcli.c を使用することもできます 。)
/* From the CLI sample utilcli.c */ /* ... */ /* fetch each row and display */ sqlrc = SQLFetch( hstmt ) ; if (sqlrc == SQL_NO_DATA_FOUND) { printf("\nData not found.\n"); }
参照