メニューボタン
IBMi海外記事2015.12.09

初めて見るSQL記述子

Paul Tuohy 著

SQL 記述子は、動的 SQL ステートメントの構築、または動的 SQL ステートメントの結果の処理に関して、驚くような柔軟性を発揮できます。しかし、この記事では概要を説明していますので、SQL 記述子をどのように使用して動的 SQL ステートメントを構築するのか見てみましょう。処理結果での使用については今後の記事で説明します。

前提として、以下の SQL ステートメントを RPG プログラムに組み込む必要があります。

技術情報01

難しい点は、部門コード、雇用日、生年月日の比較値が提供されている、またはされていない場合があるということです。したがって、where 節 (組み込む必要がある場合) は 3 つの列の組み合わせと対照している可能性があります。

以下の 3 つのうちいずれかの方法でこの難しさに取り組むことができます。

  1. 静的SQLを使用する
  2. 比較値を含んだ動的ステートメントを構築する
  3. パラメーター・マーカーとSQL記述子を使用する動的ステートメントを構築する

以下のサンプル・プログラムでは、必要な select ステートメントに同じ複数行フェッチを実行しています。プログラム面では、ステートメントがどのように構築され、実行されているかどうかが異なります。

静的SQLを使用する

以下のコード片は、静的 SQL を使用して select を実行しているプログラムを示しています。比較値が提供されているかどうかに関係なく、常に 3 つの列に対して比較することが解決法です。

部門コードに対するテストは等比較です。「どの値にも等しい」汎用値を持つことは不可能なため、等比較の代わりに BETWEEN 比較を使用します。作業フィールドを 2 つ (p_fromDept および p_fromDept) 使用して、必要な範囲を設定します。部門コードが要求されていない場合、可能な限り最低値と可能な限り最高値の組み合わせはどれになるでしょうか。また部門コードが提供されている場合に、要求されている部門から要求されている部門間の組み合わせはどれになるでしょうか。

~以上について比較しているため、日付が 2 つあると少し簡単になります。デフォルトでは、比較値を可能な限り最低の日付にして、必要な場合に要求された日付を使用してください。

技術情報02

ちょっと見るだけではエレガントな解決法に見えますが、実際はそうではありません。クエリー・エンジンに以下のような不要な作業を実行するよう要求しています。

  • 必要、不要にかかわらず、常に列を比較する。
  • 可能性として、すべての行を返すとわかっている比較をする。
  • 部門については、EQUAL比較ではなく、BETWEEN比較をする。

かつてなら、静的 SQL を使用する方が動的 SQL を使用するより早いという議論ができたかもしれませんが、そのようなことはもはやありません。では、2 番目の解決法に行きましょう。

動的ステートメントを構築する

次に示すコードは、動的 SQL ステートメントを構築するプログラムを示しています。プログラムのロジックは、比較値などの必要な「where」節を準備するステートメントの一部として構築します。

技術情報03

このコードは管理できますが、作成してデバッグするのに最も簡単なコードというわけではありません。(数えきれないほど QUOTE を除外したことがあります)。

このケースでは当てはまりませんが、長い汎用ホスト変数を置換値に使用している場合、インジェクション攻撃の可能性もあります。

SQL記述子を使用して動的ステートメントを構築する

動的 SQL ステートメントによる設定は、可能な限りパラメーター・マーカーを使用することです。この場合の難しい点は、パラメーター・マーカーが 1 つ、2 つ、3 つある、またはない場合があり、どのマーカーがどのパラメーター用なのか整合性がないことです。この難しさに加えて、OPEN ステートメントで提供されるホスト変数の数はステートメントのマーカーの数と対応する必要があります。

SQL 記述子はこれらの問題を克服するのに役立ちます。SQL 記述子では、かつて特殊データ構造 (SQLDA) および構造内のフィールドの知識を含める必要がありました。しかし V5R4 でははるかに簡単に SQL 記述子を扱うことができる方法が導入されました。

SQL 記述子とパラメーター・マーカーの使用に関する基本原理は以下のとおりです。

  1. 記述子を割り当てます。
  2. パラメーターのパラメーター・マーカーを使用して、必要なパラメーターごとに SQL ステートメントに where 条件を追加します。
  3. 比較値を必要なパラメーターごとに Descriptor に追加します。値だけでなく、各パラメーターのタイプおよび (必要な場合は) 長さも指定する必要があります。
  4. SQL記述子を使用してカーソルを開けます。

注意する重要なポイントは、比較値 (組み込む必要がある場合) ステートメントの左から右へ順番に追加され、対応する値が記述子に追加されているという点です。

次のコードは、パラメーター・マーカーを使用して動的 SQL ステートメントを構築し、SQL 記述子を使用して必要なパラメーター値を提供するプログラムです。この次のコード片を見る際に、詳細は以下のコールアウトを参照してください。

A. 記述子名にリテラルを使用できますが、名前の指定にホスト変数を使用する場合、より柔軟性が実現されます。後で名前を変更する場合、1 か所でのみ変更する必要があります。

B. 名前の付いた固定情報を使用して、WHERE 節のコンポーネントを提供します。各コンポーネントには必要なパラメーター・マーカーがあります。それらの QUOTES には必要ありません。

C. 記述子を割り当て、最大パラメーター数 (ここでは 3 つ) を指定します。

D. 部門コードに対して比較を行う場合、where 節に比較値を追加し、パラメーター値を記述子に追加します。

E. SET DESCRIPTOR ステートメントは、必要なパラメーター番号の値を設定します。これは、構築済みステートメントのマーカーの順序です。TYPE はデータ・タイプを示します (1 は文字)。LENGTH は提供中データの長さです。データは比較に使用する値です。

F. 雇用日と生年月日に対するプロセスを比較します。

G. TYPE は日付/時間/タイムスタンプでは 9、DATE_TIME_INTERVAL_CODE が 1 の場合、指定された値は日付であることを示します。

H. SET DESCRIPTOR と COUNT を使用して、記述子に追加されたパラメーターの数を示します。

I. カーソルを開く場合、「データが登録された」SQL 記述子を使用して、必要なパラメーター値を指定します。

J. それが終わったら、記述子を解除します。

技術情報04

まだなんとなく面倒くさい (動的 SQL が常にそうであるように) ものの、SQL 記述子を使用すると、パラメーターの使用および 1 か所での値の指定をコーディングできます。

その他の検討事項

SQL 記述子はプログラムに範囲を限定することを意味する LOCAL、または範囲が SQL セッションに限定される GLOBAL として割り当てでき、この記述子は他のプログラムで使用することができます。

TYPE で利用できるデータ・タイプ・コード一式については、SQL リファレンス・マニュアルの SET DESCRIPTOR の記述を参照してください。

この記事では、動的 SQL ステートメントで SQL 記述子をどのように使用して変数パラメーターを設定できるかを示しました。これは数ある SQL 記述子の使用方法の 1 つに過ぎません。例えば、それらを使用して select 節が変数の動的ステートメントから情報を取得することもできます。しかし、それは次号にしましょう。

あわせて読みたい記事

PAGE TOP