BEGIN ... END ステートメント

BEGIN ... END ステートメントは、BEGIN 内で定義されたステートメントおよび END キーワードに、単一ステートメントの状況を与えます。

これにより、含まれているステートメントが以下のようになります。
  • 関数またはプロシージャーの本体になります。
  • ハンドラーによって例外が処理されます。
  • LEAVE ステートメントによって実行が中止されます。

構文

2 番目の Label を取れるのは、最初の Label がある場合だけです。Label が 2 つともある場合、それらの Label は同一でなければなりません。同じレベルの 2 つ以上のラベル付きステートメントが同じ Label を持つことは可能ですが、2 番目の Label の利点は部分的に否定されます。その利点とは、ラベルがあいまいさなしに正確に各 END をその BEGIN と一致させることです。ただし、Statements 内でネストされたラベル付きステートメントが同じ Label を持つことはできません。なぜなら、この場合 ITERATE と LEAVE ステートメントの動作があいまいになるからです。

変数の有効範囲

新しいローカル変数の有効範囲の開始地点は、BEGIN の開始地点の直後となります。このため、このステートメント内で宣言された変数はすべて、終了地点となる END に到達した時点で有効範囲は終了します。ローカル変数の名前が既存の変数と同じである場合、宣言後に出現するその名前への参照ではローカル変数にアクセスします。以下に例を示します。
DECLARE Variable1 CHAR 'Existing variable';

-- A reference to Variable1 here returns 'Existing variable'

BEGIN
  -- A reference to Variable1 here returns 'Existing variable'

  DECLARE Variable1 CHAR 'Local variable'; -- Perfectly legal even though
the name is the same

  -- A reference to Variable1 here returns 'Local variable'
END;

ATOMIC

ATOMIC を指定すると、一度にメッセージ・フローの 1 つのインスタンス (つまり 1 つのスレッド) のみ、特定の BEGIN ATOMIC... END ステートメント (スキーマとラベルで識別される) のステートメントを実行できます。ラベルがない場合、長さゼロのラベルが指定されている場合と同様の動作になります。

BEGIN ATOMIC の構成は、共用変数に多数の変更を加える必要がある場合や、他のインスタンスがデータの中間状態を参照しないようにすることが重要な場合に便利です。次のコードの例をご覧ください。
CREATE PROCEDURE WtiteSharedVariable1(IN NewValue CHARACTER)
SharedVariableMutex1 : BEGIN ATOMIC
  -- Set new value into shared variable
END;

CREATE FUNCTION ReadSharedVariable1() RETURNS CHARACTER
SharedVariableMutex1 : BEGIN ATOMIC
  DECLARE Value CHARACTER;
  -- Get value from shared variable
  RETURN Value;
END;
最後の例では、プロシージャー WriteSharedVariable1 と関数 ReadSharedVariable1 が同じスキーマ中にあり、同じフロー内のノードで使用されることを想定しています。しかし、プロシージャーと関数がモジュール内に含まれているかどうかや、同じノードまたは別のノードのどちらで使用されるかは、問題になりません。ブローカーは、特定の時点で、1 つのスレッドのみが atomic セクション内のステートメントを実行していることを確認します。したがって、例えば 2 つの同時書き込みや同時読み取りと書き込みが順次実行されているかが確認されます。以下の点に注意してください。
  • 逐次化はフローに限定されます。スキーマとラベルが同じ BEGIN ATOMIC... END ステートメントを使用する 2 つのフローは並行して実行できます。この点については、1 つのフロー中の複数インスタンスと 1 つのフローの複数コピーは同等ではありません。
  • 逐次化はスキーマとラベルによって限定されます。複数の Atomic BEGIN ... END ステートメントが別個のスキーマ内に指定されていたり、指定されているラベルが異なっていたりすると、それらのステートメントは相互作用しません。
注: 望むなら、別の見方をすることもできます。メッセージ・フロー、スキーマ、およびラベルの組み合わせごとに、ブローカーは mutex により、その mutex に関連したステートメントに同時アクセスできないようにします。

直接的にも間接的にも BEGIN ATOMIC... END ステートメントをネストしないでください"永久ループ" になる可能性があります。したがって、atomic ブロック内で PROPAGATE ステートメントを使用しないでください。

複数のインスタンスでデプロイされることのないないフロー中で BEGIN ATOMIC 構成を使用する必要はありません (しかし使用する可能性がないと見なすのは得策ではありません)。共用変数への読み書きで BEGIN ATOMIC 構成を使用する必要もありません。ブローカーは、常に安全に共用変数に新しい値を書き込み、安全に共用変数から最新の値を読み取ります。ATOMIC は、アプリケーションにとって中間結果を参照することが機密である場合にのみ必要です。

次の例をご覧ください。
DECLARE LastOrderDate SHARED DATE;
...
SET LastOrderDate = CURRENT_DATE;
...
SET OutputRoot.XMLNSC.Data.Orders.Order[1].Date = LastOrderDate;
この例では、LastOrderDate をあるスレッドが定期的に更新し、別のスレッドが定期的に読み取ることを想定しています。ATOMIC を使用する必要はありません。なぜなら 2 番目の SET ステートメントは常に有効な値を読み取るからです。更新と読み取りが非常に近い時点で行われると、古い値か新しい値のどちらが読み取られるかは分かりませんが、必ずそのどちらかになります。結果がガーベッジになることはありません。
しかし、次の例をご覧ください。
DECLARE Count SHARED INT;
...
SET Count = Count + 1;
この例では、複数のスレッドが定期的に SET ステートメントを実行していることを想定しています。この場合、ATOMIC を使用する必要が生じます。なぜなら、2 つのスレッドがほぼ同じ瞬間に Count を読み取り、同じ値を取得する可能性があるからです。両方のスレッドとも追加を実行し、両方とも同じ値を戻して保管します。したがって、最終結果は N+1 になり、N+2 にはなりません。

ブローカーはこのロックより高水準なロック (SET ステートメント全体をカバーするロックなど) を自動的に提供しません。なぜなら、この種のロックは "永久ループ" を起こしやすいからです。

ヒント

BEGIN ... END ステートメントを、常に 1 回だけループするループ構成体と考えることができます。BEGIN ... END ステートメント内でネストされた ITERATE または LEAVE ステートメントの効果は予想どおりになります。制御は END の次のステートメントに転送されます。BEGIN ... END ステートメント内で ITERATE または LEAVE を使用することは、明確な結果が出ているかエラーが起きたために長々とした計算を中止する必要のある場合に有効です。

関連概念
ESQL の概要
関連タスク
ESQL の開発
関連資料
構文図: 使用可能なタイプ
ESQL のステートメント
特記事項 | 商標 | ダウンロード | ライブラリー | サポート | フィードバック
Copyright IBM Corporation 1999, 2006 最終更新: 08/21/2006
ak04940_