BEGIN … END - Advanced SQL Engine - Teradata Database

Teradata Vantage™ - SQLストアド プロシージャおよび埋め込みSQL

Product
Advanced SQL Engine
Teradata Database
Release Number
17.05
17.00
Published
2020年6月
Language
日本語
Last Update
2021-03-30
dita:mapPath
ja-JP/xqq1557098602407.ditamap
dita:ditavalPath
ja-JP/xqq1557098602407.ditaval
dita:id
B035-1148
Product Category
Software
Teradata Vantage

目的

ストアド プロシージャ内の複合文を区切ります。

呼び出し

実行可能形式。

ストアド プロシージャのみ。

構文

[ label_name : ] BEGIN
  [ local_declaration ] [...]
  [ cursor_declaration ] [...]
  [ condition_handler ] [...]
  [ statement ] [...]
END [ label_name ] ;
label_name
BEGIN…END複合文のオプションのラベル。
開始ラベルはコロン(:)で終わっている必要があります。最後のラベルは必須ではありません。ただし、最後のラベルを指定する場合は、それと同等の開始ラベルも指定する必要があります。
BEGIN…END文のラベルは、この文に含まれるどの文でも再使用できません。
ストアド プロシージャ内に入れ子の複合文を指定する場合は、各BEGIN…END文にラベル名を使用することが推奨されます。
local_declaration
DECLARE文を使用して宣言されたローカル変数、または、DECLARE HANDLER文を使用して宣言された条件。
入れ子の複合文の場合、外側の複合文で宣言された変数および条件は内側の複合文で再使用できます。
ローカル変数には、その変数が宣言された複合文のラベルを付けることができます。これは、入れ子にされた複合文でローカル変数を再使用したときに混乱が生じないようにするのに役立ちます。
cursor_declaration
DECLARE CURSOR文を使用して宣言されたカーソル。
入れ子の複合文の場合、外側の複合文で宣言されたカーソルは内側の複合文で再使用できます。
condition_handler
DECLARE HANDLER文を使用して宣言された条件ハンドラー。
condition_handlerの中では、条件ハンドラーのアクションの文を囲むために、BEGIN…END複合文を使用することができます。
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 ストアド プロシージャの作成中のストアド プロシージャ本体の構文解析時に構文エラーを戻します。

宣言の順序

BEGIN-END複合文では、任意の数の宣言、およびメイン タスクを実行するための文を指定できます。これらはすべてオプションで指定するものですが、指定する場合には、以下に示すBEGIN-ENDブロック内の順序に従う必要があります。
  1. ローカル変数と条件宣言。
  2. カーソル宣言。
  3. 条件ハンドラーの宣言。
  4. 以下のうちの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を参照してください。
  • ローカル変数と条件宣言については、DECLAREDECLARE CONDITIONを参照してください。
  • カーソル宣言については、カーソル宣言を参照してください。
  • 条件ハンドラーの宣言については、DECLARE HANDLER(基本構文)およびそれ以降の“DECLARE HANDLER”セクションを参照してください。
  • 静的または動的SQL文、制御文、および文のリストを含んだ複合文については、ストアド プロシージャのDDL文を参照してください。
  • 内側の複合文のローカル変数、条件、パラメータ、またはカーソル名については、ITERATEを参照してください。