目的
ストアド プロシージャ内の複合文を区切ります。
呼び出し
実行可能形式。
ストアド プロシージャのみ。
構文
- label_name
- BEGIN…END複合文のオプションのラベル。
- local_declaration
- DECLARE文を使用して宣言されたローカル変数、または、DECLARE HANDLER文を使用して宣言された条件。
- cursor_declaration
- DECLARE CURSOR文を使用して宣言されたカーソル。
- condition_handler
- DECLARE HANDLER文を使用して宣言された条件ハンドラー。
- statement
- 次のいずれか。
- ストアド プロシージャでサポートされるDML、DDL、またはDCL文。これには、動的SQL文が含まれます。
- 制御文、BEGIN…ENDを含む。
ANSI準拠
BEGIN…ENDはANSI/ISO SQL:2011に準拠しています。
許可
なし。
LEAVEおよびITERATEで参照されるラベル
ラベル付けされたBEGIN…END文内のLEAVE文またはITERATE文に関連付けられたラベルで、BEGIN…ENDブロックのラベルを参照する場合は、次の規則が適用されます。
文 | 実行内容 |
---|---|
LEAVE | 実行時にラベルが関連付けられていたBEGIN…END文が終了します。終了したブロックの次にある文に制御権が移動します。 プロシージャに1つのBEGIN…END文だけが存在する場合や、終了したブロックがストアド プロシージャ本体の最後の文だった場合、この種の終了は、ストアド プロシージャの正常完了と見なされます。 |
ITERATE | ストアド プロシージャの作成中のストアド プロシージャ本体の構文解析時に構文エラーを戻します。 |
宣言の順序
- ローカル変数と条件宣言。
- カーソル宣言。
- 条件ハンドラーの宣言。
- 以下のうちの1つ。
- 単一の静的または動的SQL文、もしくは制御文
- 文のリストを格納した複合文
各タイプの宣言は、それぞれにまとめて指定してください。同じブロックの中に別のタイプの宣言や別の文を混ぜることはできません。
複合文が入れ子になっている場合は、宣言のいくつか、あるいはすべてをBEGIN-ENDブロックで指定できます。あるいは、BEGIN-ENDブロックを使用しなくても構いません。
ルール
- 必須ではありませんが、ストアド プロシージャの定義には、通常1つのBEGIN…END文が含まれます。ストアド プロシージャ内の他のすべての文は、この複合文の中で指定されなければなりません。
- また、condition_handler宣言にBEGIN…END文を使用して、ハンドラー アクションの文のリストを囲むこともできます。
- BEGIN…END複合文は、入れ子にすることが可能です。入れ子のレベルに制限はありません。
- BEGIN文は、すべてキーワードENDで終わらなければなりません。
- BEGIN…END文には、ラベルを付けることができます。BEGIN…END文に関連付けられたラベルの適用範囲は、その文全体です。
これには、入れ子にされたすべての複合文が含まれますが、複合文や入れ子にされた複合文の中で宣言されたハンドラーは含まれません。
- ストアド プロシージャは、BEGIN…END文の中から実行できます。
- 複合文の中で宣言されたローカル変数、条件、パラメータ、およびカーソルの適用範囲は、入れ子にされたすべての複合文を含む、複合文全体です。
- 内側の複合文のローカル変数、条件、パラメータ、またはカーソルの名前が外側の複合文にある名前と同じになった場合、実行時には、内側の複合文にあるローカル変数、条件、パラメータ、またはカーソルの名前が外側の複合文よりも優先されます。
- ハンドラー アクションの文以外の文によって複合文の中に発生した例外条件、完了条件、およびユーザー定義条件は、複合文の中で処理されます。
内側の複合文の条件に使用できる適切なハンドラーがない場合は、その条件を外側の複合文に伝えて適切なハンドラーを検索します。
- アクションの句で発生した例外条件、完了条件、およびユーザー定義条件は、アクション句の中に定義されているハンドラーで処理できます。
ハンドラ アクションで発生する条件がアクション句の中で処理されない場合、その条件は適切なハンドラーの検索のために外側に伝搬されることはありません。これは、処理されないままになります。唯一の例外は、RESIGNAL文です。その条件は、ハンドラー内の複合文のアクション句の外に伝搬されます。
以下の表では、処理されない例外条件、完了条件、ユーザー定義条件を比較しています。
処理されない条件の種類 | 結果 |
---|---|
例外条件またはユーザー定義条件 | ハンドラーが終了し、そのハンドラーを呼び出した元々の条件が、適切なハンドラーを探すために外側に伝搬されます。 元の条件に対する適当なハンドラーが存在しない場合、ストアド プロシージャは終了します。 |
完了条件 | 条件は無視され、ハンドラーアクションは次の文へ続行されます。 |
例: 入れ子の複合文を含む有効なストアド プロシージャ
次の例は、入れ子の複合文を含む有効なストアド プロシージャを示すものです。
CREATE PROCEDURE spAccount(OUT p1 CHARACTER(30)) L1: BEGIN DECLARE i INTEGER; DECLARE DeptCursor CURSOR FOR SELECT DeptName from Department; DECLARE CONTINUE HANDLER FOR SQLSTATE VALUE '23505' L2: BEGIN SET p1='Failed To Insert Row'; END L2; L3: BEGIN INSERT INTO table_1 VALUES(1,10); IF SQLCODE <> 0 THEN LEAVE L1; END L3; INSERT INTO table_2 VALUES(2,20); END L1;
この例のプロシージャ本体には、L1というラベルの付いたブロックがあります。このブロックには、ローカル変数の宣言、カーソル宣言、条件ハンドラーの宣言、L3というラベルの付いた入れ子のブロック、およびその他の文が格納されています。
1つ目のINSERT文とIF文は、L3とラベル付けされた内側の複合文に属し、2つ目のINSERT文とIF文は、L1とラベル付けされた外側のブロックに属します。
L2とラベル付けされたBEGIN…ENDブロックは、ハンドラーの宣言の一部です。
例: 内側の複合文での外側の複合文の変数の使用
次の例は、複合文のラベルで変数を修飾することによって、内側の複合文で外側の複合文の変数を使用する様子を示しています。
CREATE PROCEDURE spSample1(INOUT IOParam1 INTEGER, OUT OParam2 INTEGER) L1: BEGIN DECLARE K INTEGER DEFAULT 10; L2: BEGIN DECLARE K INTEGER DEFAULT 20; SET OParam2 = K; SET IOParam1 = L1.K; END L2; ... END L1;
Kは、外側の複合文L1で宣言されたローカル変数で、これを内側の複合文L2で再使用します。
ストアド プロシージャの実行の後、パラメータOParam2は、L2で定義されたKのデフォルト値20をとります。これは、内側のブロックで行なわれた変数のローカル定義の方が、外側のブロックの定義よりも優先されるためです。
その一方で、IOParam1 は複合ステートメントのラベル L1 と 2 番目の SET ステートメントで K が限定されるので、10 である L1 で定義されている K のデフォルト値をとります。
例: ローカル変数と条件ハンドラーの宣言を備えた有効なストアド プロシージャの作成
次の例では、ローカル変数と条件ハンドラーの宣言を備えた有効なストアド プロシージャを作成します。このストアド プロシージャの作成の前にtable1が削除されたと想定してください。
ストアド プロシージャ本体のINSERTステートメントで’42000’の例外条件が発生し、EXITハンドラーが呼び出されます。ハンドラー アクション句内のDROP TABLE文は、別の’42000’例外を生成します。これは、CONTINUEハンドラーで処理されます。
CREATE PROCEDURE spSample3(OUT p1 CHARACTER(80)) BEGIN DECLARE i INTEGER DEFAULT 20; DECLARE EXIT HANDLER FOR SQLSTATE '42000' BEGIN DECLARE i INTEGER DEFAULT 10; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET p1 = 'Table does not exist'; DROP TABLE table1; CREATE TABLE table1 (c1 INTEGER); INSERT INTO table1 (i); END; INSERT INTO table1 VALUES(1000,'aaa'); /* table1 does not exist */ END;
例: 同じSQLSTATEコードのローカル変数と条件ハンドラーの再使用
次の例は、入れ子になっていない複合文で、同じSQLSTATEコードのローカル変数と条件ハンドラーを再使用する、有効な方法を示しています。
CREATE PROCEDURE spSample (OUT po1 VARCHAR(50), OUT po2 VARCHAR(50)) BEGIN DECLARE i INTEGER DEFAULT 0; L1: BEGIN DECLARE var1 VARCHAR(25) DEFAULT 'ABCD'; DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' SET po1 = "Table does not exist in L1'; INSERT INTO tDummy (10, var1); -- Table Does not exist END L1; L2: BEGIN DECLARE var1 VARCHAR(25) DEFAULT 'XYZ'; DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' SET po2 = "Table does not exist in L2'; INSERT INTO tDummy (i, var1); -- Table Does not exist END L2; END;
関連トピック
- LEAVE文については、LEAVEを参照してください。
- ITERATE文については、ITERATEを参照してください。
- ローカル変数と条件宣言については、DECLAREとDECLARE CONDITIONを参照してください。
- カーソル宣言については、カーソル宣言を参照してください。
- 条件ハンドラーの宣言については、DECLARE HANDLER(基本構文)およびそれ以降の“DECLARE HANDLER”セクションを参照してください。
- 静的または動的SQL文、制御文、および文のリストを含んだ複合文については、ストアド プロシージャのDDL文を参照してください。
- 内側の複合文のローカル変数、条件、パラメータ、またはカーソル名については、ITERATEを参照してください。