ページング・カーソル
注: この記事で出てくるコードはここからダウンロードできます。
RPG で組み込み SQL を使用している場合に、大規模リストをページングする場合に使用する技法の 1 つを教えましょう。この方法は、対話式 (グリーン・スクリーン) と Web 環境の両方で使用できるルーチンを作成するのに必要だったときに出来ました。以下のような 2 つの大きな課題がありました。
- 「ページ」のサイズはさまざまです。この処理は極めて簡単でした。最大ページ・サイズを決めるだけでした。
- Web インターフェースは永く続くわけではありません。つまり、さまざまなサーバー・ジョブがさまざまなページング要求を処理しています。言い換えれば、(SQL SELECT ステートメント) のカーソルがリトリーブのたびに閉じる必要があるということです。しかし、SQL Query Engine (SQE) は非常に賢く、あるジョブで行った作業を別のジョブに利用できます。そのため、各ページ要求のカーソルの開閉の影響は最小限になります。
注: この記事で出てくるコードはここからダウンロードできます。
RPG で組み込み SQL を使用している場合に、大規模リストをページングする場合に使用する技法の 1 つを教えましょう。この方法は、対話式 (グリーン・スクリーン) と Web 環境の両方で使用できるルーチンを作成するのに必要だったときに出来ました。以下のような 2 つの大きな課題がありました。
- 「ページ」のサイズはさまざまです。この処理は極めて簡単でした。最大ページ・サイズを決めるだけでした。
- Web インターフェースは永く続くわけではありません。つまり、さまざまなサーバー・ジョブがさまざまなページング要求を処理しています。言い換えれば、(SQL SELECT ステートメント) のカーソルがリトリーブのたびに閉じる必要があるということです。しかし、SQL Query Engine (SQE) は非常に賢く、あるジョブで行った作業を別のジョブに利用できます。そのため、各ページ要求のカーソルの開閉の影響は最小限になります。
要件
必要な情報のページを取得するだけでなく、情報がどのように要求されたのか、またルーチンから戻されるその他の情報について、いくつか他の要件がありました。
ルーチンでは、入力パラメーターで次を指定する必要がありました。
- ページの行数
- 取得するページ
- どのページを取得するかに関するオフセット。つまり、取得したページは以前のパラメーターとこの番号を足したものになります。これにより、呼び出し元でロールフォワードまたはロールバック・ロジックが有効になります。
ルーチンでは、出力パラメーターで次を指定する必要がありました。
- 取得したページ
- 合計ページ数
- 合計行数
- このページの行数
これら SQL ページング・ルーチンのいずれかのコール・インターフェースを、次のコードに示します。
テンプレート b_list_Employees の定義を示すコードを見てみましょう。このテンプレートは、データ取得に使用したホスト変数配列の定義で使用しています。
SQL ビット
各コールでカーソルを開閉するということは、組み込み SQL が極めて単純であるということです。以下のコード・スニペットは、SQL ページング・ルーチンを示します。プロセスは次の通りです。
- カーソルを宣言します。カーソルはインセンシティブ・カーソルとして定義され、後の GET DIAGNOSTICS で正しい数の行が戻されるようにします。
- カーソルを開きます。
- GET DIAGNOSTICS を使用して、結果セットの合計行数を判断します。
- calculate_Page_Data() サブプロシージャーを呼び出し、戻されたパラメーター値 (合計ページ数など) を計算しますが、最も重要なことは、結果セットから取得する最初の行のオフセットを計算することです。しばらくの間 calculate_Page_Data() を見てみましょう。
- マルチ行フェッチを使用して、結果セットから要求された数の行 (ページ・サイズ) を取得します。FETCH RELATIVE は正しいページを取得するよう、計算された行オフセットで使用されます。
- 取得した行数を確保します。
- カーソルを閉じます。
calculate_Page_Data() サブプロシージャー
ページ・データの計算プロセスは、この方法を使用するすべての SQL ページング・プロシージャーで同じであるため、自分のサブプロシージャーにプットすることは理にかなっています。calculate_Page_Data() を以下のコードに示します。このサブプロシージャーの主な目的は、結果セットの合計行数をページ・サイズで割った値に基づいて、結果セットの合計ページ数を計算することです。また、要求されたページに次ページのパラメーターを足したものに、ページ単位の行数を掛けた値に基づいて、要求されたページの最初の行のオフセットを計算することです。また calculate_Page_Data() は、要求されたパラメーター (要求ページ、ページ単位の行など) が有効で、結果セットの境界内にあることを確認します。
実践する
ここからダウンロードできるプログラムは、この記事で示す例の使用法を示しています。例は標準 SQL サンプル・データベースの EMPLOYEE 表を活用していますが、あなたの好みの表に自由に変更してください。
通常は、すべてのサブプロシージャーはサービス・プログラムにあり、少なくとも calculate_Page_Data() サブプロシージャーは、サービス・プログラムに属しています。
これがお役に立つことを祈っています。
Paul Tuohy : iSeries コンサルティング企業である ComCon の CEO で、RPG & DB2 Summit カンファレンスを主催する System i Developer の共同創始者の 1 人。また、定期的に COMMON カンファレンスで講演を行う受賞歴のある弁士で、「Re-engineering RPG Legacy Applications」、「The Programmers Guide to iSeries Navigator」、and the self-study course called 「iSeries Navigator for Programmers」という自己学習コースの著者。Paul への質問やコメントは IT Jungle Contact ページから Ted Holt へお願いします。
要件
必要な情報のページを取得するだけでなく、情報がどのように要求されたのか、またルーチンから戻されるその他の情報について、いくつか他の要件がありました。
ルーチンでは、入力パラメーターで次を指定する必要がありました。
- ページの行数
- 取得するページ
- どのページを取得するかに関するオフセット。つまり、取得したページは以前のパラメーターとこの番号を足したものになります。これにより、呼び出し元でロールフォワードまたはロールバック・ロジックが有効になります。
ルーチンでは、出力パラメーターで次を指定する必要がありました。
- 取得したページ
- 合計ページ数
- 合計行数
- このページの行数
これら SQL ページング・ルーチンのいずれかのコール・インターフェースを、次のコードに示します。
テンプレート b_list_Employees の定義を示すコードを見てみましょう。このテンプレートは、データ取得に使用したホスト変数配列の定義で使用しています。
SQL ビット
各コールでカーソルを開閉するということは、組み込み SQL が極めて単純であるということです。以下のコード・スニペットは、SQL ページング・ルーチンを示します。プロセスは次の通りです。
- カーソルを宣言します。カーソルはインセンシティブ・カーソルとして定義され、後の GET DIAGNOSTICS で正しい数の行が戻されるようにします。
- カーソルを開きます。
- GET DIAGNOSTICS を使用して、結果セットの合計行数を判断します。
- calculate_Page_Data() サブプロシージャーを呼び出し、戻されたパラメーター値 (合計ページ数など) を計算しますが、最も重要なことは、結果セットから取得する最初の行のオフセットを計算することです。しばらくの間 calculate_Page_Data() を見てみましょう。
- マルチ行フェッチを使用して、結果セットから要求された数の行 (ページ・サイズ) を取得します。FETCH RELATIVE は正しいページを取得するよう、計算された行オフセットで使用されます。
- 取得した行数を確保します。
- カーソルを閉じます。
calculate_Page_Data() サブプロシージャー
ページ・データの計算プロセスは、この方法を使用するすべての SQL ページング・プロシージャーで同じであるため、自分のサブプロシージャーにプットすることは理にかなっています。calculate_Page_Data() を以下のコードに示します。このサブプロシージャーの主な目的は、結果セットの合計行数をページ・サイズで割った値に基づいて、結果セットの合計ページ数を計算することです。また、要求されたページに次ページのパラメーターを足したものに、ページ単位の行数を掛けた値に基づいて、要求されたページの最初の行のオフセットを計算することです。また calculate_Page_Data() は、要求されたパラメーター (要求ページ、ページ単位の行など) が有効で、結果セットの境界内にあることを確認します。
実践する
ここからダウンロードできるプログラムは、この記事で示す例の使用法を示しています。例は標準 SQL サンプル・データベースの EMPLOYEE 表を活用していますが、あなたの好みの表に自由に変更してください。
通常は、すべてのサブプロシージャーはサービス・プログラムにあり、少なくとも calculate_Page_Data() サブプロシージャーは、サービス・プログラムに属しています。
これがお役に立つことを祈っています。
Paul Tuohy : iSeries コンサルティング企業である ComCon の CEO で、RPG & DB2 Summit カンファレンスを主催する System i Developer の共同創始者の 1 人。また、定期的に COMMON カンファレンスで講演を行う受賞歴のある弁士で、「Re-engineering RPG Legacy Applications」、「The Programmers Guide to iSeries Navigator」、and the self-study course called 「iSeries Navigator for Programmers」という自己学習コースの著者。Paul への質問やコメントは IT Jungle Contact ページから Ted Holt へお願いします。