CLI の手引きおよび解説書

配列への結果セットの取り出し

アプリケーションが行う最も一般的なタスクの一つに、照会ステートメントを発行してから、SQLBindCol() を使ってバインドされたアプリケーション変数中に結果セットの各行を取り出すことがあります。アプリケーションが結果セットの各列または各行を配列内に保管するよう要求する場合は、個々の取り出しの後に続いてデータのコピー操作を行うか新たに一連の SQLBindCol() 呼び出しを行って、次の取り出しのために新しい記憶域を割り当てなくてはなりません。

もう一つの方法として、アプリケーションがデータの複数行を (行の集まりを呼び出して) 一度に配列内へ取り出して、余分なデータ・コピーまたは余分な SQLBindCol() 呼び出しのオーバーヘッドを取り除くことができます。
注:オーバーヘッドを少なくする 3 番目の方法は、単独でも配列でも使用できますが、バインドの相対位置を指定することです。毎回再バインドするよりも、相対位置を使用すると、 SQLFetch() または SQLFetchScroll() への次回の呼び出しで使用される新しいバッファー・アドレスおよび長さ / 標識アドレスを指定することができます。これは行相対位置のバインドでのみ使用可能であり、列バインドの相対位置で説明しています。

結果セットを配列に取り出す場合、SQLBindCol() を使用して、アプリケーションの配列変数用の記憶域を割り当てることも行います。省略時設定では、行のバインドは列方向です。これは前のセクションに記述されている、 SQLBindParameter() を使用して入力パラメーター値の配列をバインドする場合とは対称的です。

図 12. 列方向バインド


列方向バインド

図 13. 行方向バインド


行方向バインド

SQLFetchScroll() は、スクロール可能カーソル、つまり結果セット内の任意の位置から上方および下方に移動する機能をサポートします。これは、列方向および行方向のバインドの両方で使用できます。詳細については、スクロール可能カーソルを参照してください。

列方向バインドによる配列データの取り出し

図 12 は、列方向バインドの論理視点です。 図 14 の右側に、列方向取り出しの関数の流れを示してあります。

列方向の配列取り出しを指定するには、アプリケーションで SQL_ATTR_ROW_ARRAY_SIZE 属性を指定して SQLSetStmtAttr() を呼び出し、一度に取り出す行数を示します。 SQL_ATTR_ROW_ARRAY_SIZE 属性の値が 1 よりも大きいと、DB2 CLI は、処理を行う据え置き出力データ・ポインターと長さポインターは、結果セットの列のデータと長さのある 1 つの要素を指すものではなく、データと長さの配列を指すものであることを認識します。

次に、アプリケーションは SQLFetchScroll() を呼び出してデータを取り出します。データを返すとき、 DB2 CLI は SQLBindCol() の最大バッファー・サイズ引き数 (BufferLength) を使用し、データの連続行を配列内のどこに保管するのかを判別します。各要素を返すのに使用できるバイト数は、据え置き長さ配列に保管されています。結果セットの行数が SQL_ATTR_ROW_ARRAY_SIZE 属性値よりも大きい場合に、すべての行を取り出すには、複数回 SQLFetchScroll() を呼び出す必要があります。

行方向バインド・データへの配列データの戻り

アプリケーションは行方向バインド、つまり結果セットの 1 行全体を 1 つの構造に関連付けることも行えます。この場合、行の集まりは構造の配列中に取り出されます。個々の構造には 1 つの行のデータおよび関連付けられた長さフィールドがあります。 図 13 は、行方向バインドを図示しています。

行方向の配列取り出しを行うには、アプリケーションで SQL_ATTR_ROW_ARRAY_SIZE 属性を指定して SQLSetStmtAttr() を呼び出し、一度に取り出す行数を示す必要があります。さらに SQL_ATTR_ROW_BIND_TYPE 属性値を、結果列がバインドされる構造のサイズに設定して、 SQLSetStmtAttr() を呼び出さなくてはなりません。 DB2 CLI は、SQLBindCol() の据え置き出力データ・ポインターを、このような構造の配列の先頭要素の列に関するデータ・フィールド・アドレスとして扱います。据え置き出力長さポインターは、列の関連長さフィールドのアドレスとして扱います。

次に、アプリケーションは SQLFetchScroll() を呼び出してデータを取り出します。データを返すときに、 DB2 CLI は SQL_ATTR_ROW_BIND_TYPE 属性によって設定されている構造サイズを使用して、構造の配列のどこに連続行を保管するかを判別します。

図 14 は、それぞれの方式に必要な関数を示しています。左側は、一度に 1 行が選択され、取り出された行が n 行あり、それらが m 個のアプリケーション変数に入れられていることを示しています。右側は、同じ n 行が選択され、取り出されて配列に直接入れられていることを示しています。

図 14. 配列の取り出し


配列の取り出し

列バインドの相対位置

バインドの変更が生じた場合 (たとえば、次の取り出しのために)、アプリケーションはもう一度 SQLBindCol() を呼び出すことができます。これによって、バッファー・アドレスおよび使用中の長さ / 標識ポインターが変更されます。

SQLBindCol() への複数の呼び出しの代わりに、 DB2 CLI はパラメーター・バインドの相対位置もサポートしています。毎回再バインドするよりも、相対位置を使用すると、 SQLFetch() または SQLFetchScroll() への次回の呼び出しで使用される新しいバッファー・アドレスおよび長さ / 標識アドレスを指定することができます。これは、行方向バインドでのみ使用できますが、アプリケーションが一度に単一行を取り出すか、または複数行を取り出すかを決めます。

列バインドの相対位置を使用するには、アプリケーションは次のステップに従ってください。

  1. 通常どおり、SQLBindCol() を呼び出します。バインドされるデータ・バッファーと、長さ / 標識バッファーのアドレスの最初のセットは、テンプレートとしての働きをします。そして、アプリケーションは相対位置を使用して、このテンプレートをいろいろな記憶場所に移動します。
  2. 通常どおり、 SQLFetch() または SQLFetchScroll() を呼び出します。返されるデータは、上記にバインドされる場所に保管されます。
  3. メモリー相対位置の値を保持する変数を設定します。

    ステートメント属性 SQL_ATTR_ROW_BIND_OFFSET_PTR は、相対位置が保管されることになる SQLINTEGER バッファーのアドレスを指します。このアドレスは、カーソルがクローズするまで有効である必要があります。

    この、余分のレベルの間接参照によって、単一のメモリー変数を使用するだけで、異なるステートメント・ハンドルにあるバインドの複数のセットについて、相対位置を保管することができます。アプリケーションは、この 1 つのメモリー変数と、変更されるすべての相対位置だけを設定する必要があります。

  4. 相対位置の値 (バイト数) を、前のステップのステートメント属性セットが指し示すメモリー位置に保管します。

    相対位置の値は、常に最初にバインドされている値のメモリー位置に加えられ、この合計が有効なメモリー・アドレスを指すことになります。

  5. 再び、 SQLFetch() または SQLFetchScroll() を呼び出します。 CLI は上記で指定される相対位置を SQLBindCol() への元の呼び出しで使用される場所に追加して、結果を保管するのがどのメモリーかを判別します。
  6. 必要に応じて上記のステップ 4 および 5 を繰り返します。

詳細については、SQLBindCol()『列バインドの相対位置』を参照してください。

列方向、行方向のバインド例

/* From the CLI sample PCALL.C */
/* ... */
    /* print result sets, if any */
    do    
    {   rc = StmtResultPrint( hstmt1);
    }	    
    while( SQLMoreResults( hstmt1) == SQL_SUCCESS);   
    
 


[ ページのトップ | 前ページ | 次ページ | 目次 | 索引 ]