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

SQL PL ラベル

Ted Holt 著

SQL PL は、とてもパワフルで覚えやすい手続型のデータベース言語です。IBMが出荷しているすべてのバージョンのDB2に入っているそれは、ラベルを使うことであらゆる実行可能ステートメントや複合ステートメントを特定できるようにしてくれます。私たちがどうしてラベルを使いたいかを考えるのに、今日ほどふさわしい日はないと思います。

最少ステップでプログラムを作ることに生きがいを感じている私は、当然無用なコードは除外しますが、中には必要のないラベルが記述されていることがあります。以下のパラグラフでは、本当にラベルが必要なケースのみ示したいと思います。

しかしまずは、いくつか基本原則があります。

  • CL 同様、ステートメントの識別に使用する場合は、ラベル名の次にコロンが続きます。お望みなら、コロンの前を空白にしたままにもできますが、必須ではありません。
  • ラベル名は以下を含むことができます。

-文字
-数字
-@ アットマーク
-ドル記号 $
-番号記号、ポンド記号、ハッシュ、三目並べ、またはシャープ記号など、人によってさまざまに呼ばれている記号 #
-下線文字(アンダースコア)

  • ラベル名は文字、@ アットマーク、ドル記号、またはシャープ記号で始まる必要があります。
  • ラベル名は同じ範囲になければ、複製できます。
  • 文字リテラルを除くその他すべてと同様、ラベル名は大文字と小文字を区別しません。
  • END xxx ステートメントにラベル名を付け加えることができますが、そのラベル名は対となる開始ラベル名と一致する必要があります。

ケース 1: 複合ステートメントを終了する
複合ステートメントはワード BEGIN と END で囲まれた SQL 宣言およびステートメントのグループです。(複合ステートメントの詳細説明については、SQL プロシージャー言語の概要を参照してください。)

終わりに達する前に、複合ステートメントを終了したい場合があるかもしれません。RPG を知っているなら、サブプロシージャーの RETURN 命令とサブルーチンの LEAVESR 命令を考えてみてください。

LEAVE ステートメントを使用して SQL PL で同じことができます。しかし、SQL LEAVE 命令コードと RPG 命令コードには大きな違いがあります。LEAVE では、たとえ終了ポイントとなるブロックが 1 つしかない場合でも、どのブロックから離れたいか、ラベルで指定する必要があります。

LEAVE を使用した必要最小限の簡単な例を示します。

技術情報code01

このプロシージャーには Main_routine と Posting_routine という 2 つの複合ステートメントがあります。Main_routine が Main_routine または Posting_routine のいずれかから離れることができている点に注目してください。

Posting_routine と Main_routine の終了ラベルは必要ありませんが、コードが読みやすくなるので私はそれらを使用するのが好きです。

ケース 2: ループを終了するか、ループの開始に戻る
LEAVE コマンドと ITERATE コマンドを使用するため、任意のループ構造 - WHILE、REPEAT、LOOP、FOR - にラベルを付けることができます。LEAVE はループを終了し、ITERATE はループ・テストに分岐します。

ループ 1:

技術情報code02

LOOP ステートメントは事務的にLoop1と名付けられカーソルを処理します。FETCH が取り出すものが何もないことを検出すると、DB2 は SQL 状態を 02000 に設定します。IF は LEAVE を実行してループを終了させます。最後のステートメントが表示された後、制御はステートメントに渡されます。例文の詳細は、SQL PL-The LOOP Loop をご覧ください。

ケース 3: 変数名を修飾する
SQL PL は、同じ範囲内でなければ同名に 2つ以上の変数を定義することを許可しています。つまり、異なる複合ステートメント内で定義する必要があります。それらの複合ステートメントの 1 つを、他の複合ステートメントと入れ子にできます。

複合ステートメントの外で定義されている変数を参照する必要がある場合、ラベルを使用して修飾することができます。骨組みコードを下記します。

技術情報code03

この例では、複合ステートメントは 3つあります。Preparation と Posting が Main_routine 内で入れ子になっています。これら 3 つは v_Code という変数を宣言していますが、それらの 3つすべての変数にアクセスできるルーチンはありません。

  • Main_routine は、 Main_routine で定義されている v_Code 変数にアクセスできます。
  • Preparation は、 Main_routine と Preparation で定義されている v_Code 変数にアクセスできます。
  • Posting は、 Main_routine と Posting で定義されている v_Code 変数にアクセスできます。

同名の変数がローカル複合ステートメントで定義されていなければ、外部複合ステートメントに定義されている変数を参照する場合、修飾は必要ありません。このプロシージャーは v_Msg という変数も定義します。修飾しなくても、3つの複合ステートメントのいずれかの中でこの変数を参照できます。 重複変数が修飾されていない場合、ローカル範囲内で定義された変数と見なされます。例えば、Preparation で修飾されていない v_Code のテストは、 Preparation で定義されている v_Code を参照します。 宣言された変数に簡単に一意の名前を指定できるため、私はこの機能を使用したことはありません。Yip et al ブックでは、同名の変数を同じプロシージャー内で宣言することを推奨していません。

ケース 4: 分岐する
GOTO コマンドはプロシージャーの別の部分に素早くコマンドを発生させます。このプロシージャー部分はラベルで特定されている必要があります。あえてわざと作成した例を示します。

技術情報code04

ラベル Skip_1 が BEGIN、つまりループ・ステートメントの前に来ていません。単に分岐する場所であるため、どのステートメントもその後に続く可能性があります。
私はGOTO が必要な SQL ルーチンを今まで作成したことはありません。その必要はありませんでした。

さて、どんな名前がありますか?

どんな名前でもステートメントを命名できます。Chuck や Bubba や BillyBob と名前を付けることはできますが、Skip はできません。なぜできないのかは私にもわかりません。

あわせて読みたい記事

PAGE TOP