条件ハンドラー は、ある条件が発生する際の SQL プロシージャーの振る舞いを決定します。一般的な DB2 条件、特定の SQLSTATE 値の定義された条件、または特定の SQLCODE 値の定義された条件に関して、 1 つまたは複数の条件ハンドラーを SQL プロシージャーで宣言することができます。一般的な条件および独自の条件を定義するための方法についての詳細は、条件ハンドラーの宣言を参照してください。
SQL プロシージャー内のステートメントによって SQLWARNING または NOT FOUND 条件が発行され、それぞれの条件に対してハンドラーを宣言した場合には、 DB2 によって制御が対応するハンドラーに渡されます。その特定の条件に対してハンドラーを宣言しなかった場合、 DB2 は SQLSTATE および SQLCODE 変数にその条件に対応する値を設定して、制御をプロシージャー本体の次のステートメントに渡します。
SQL プロシージャーのステートメントが SQLEXCEPTION 条件を起こしており、その特定の SQLSTATE または SQLEXCEPTION 条件に対してハンドラーを宣言してある場合には、 DB2 によって制御がそのハンドラーに渡されます。 DB2 が正常にハンドラーを実行する場合には、 SQLSTATE および SQLCODE 値はそれぞれ '00000' と 0 を戻します。
SQL プロシージャーのステートメントが SQLEXCEPTION 条件を起こしており、その特定の SQLSTATE または SQLEXCEPTION 条件に対してハンドラーを宣言していない場合、 DB2 は SQL プロシージャーを終了してからクライアントに戻ります。
ハンドラー宣言の一般的な形式は、以下のようなものです。
DECLARE handler-type HANDLER FOR condition SQL-procedure-statement
DB2 によって condition に合致する条件が起こされる場合には、 DB2 制御を条件ハンドラーに渡します。そして、条件ハンドラーは handler-type によって示されているアクションを実行してから、 SQL-procedure-statement を実行します。
注: | UNDO ハンドラーは ATOMIC 複合ステートメントのみで指定できます。 |
さらに、DECLARE ステートメントを使用して特定の SQLSTATE に対して独自の条件を定義できます。独自の条件を定義する方法の詳細については、 SQL 解説書 を参照してください。
注: | 条件ハンドラー内に別の条件ハンドラーを定義することはできません。 |
例: CONTINUE ハンドラー: このハンドラーは、DB2 によって NOT FOUND 条件が起こされる際に、 at_end というローカル変数に 1 という値を割り当てます。それから、DB2 は制御を、 NOT FOUND 条件を起こしたステートメントの次のステートメントに渡します。
DECLARE not_found CONDITION FOR SQLSTATE '02000'; DECLARE CONTINUE HANDLER FOR not_found SET at_end=1;
例: EXIT ハンドラー: プロシージャーは、 NO_TABLE を SQLSTATE 42704 (name は未定義名) の条件名として宣言します。 NO_TABLE の条件ハンドラーは、 Table does not exist というストリングを OUT_BUFFER という出力パラメーターに置きます。それから、そのハンドラーが宣言された複合ステートメントから SQL プロシージャーを終了させます。
DECLARE NO_TABLE CONDITION FOR SQLSTATE '42704'; DECLARE EXIT HANDLER FOR NO_TABLE BEGIN SET OUT_BUFFER='Table does not exist'; END
例: UNDO ハンドラー: SQLSTATE 42704 では、プロシージャーは SQLSTATE の名前を定義せずに UNDO 条件ハンドラーを宣言します。ハンドラーは SQL プロシージャーが現行の作業単位をロールバックするようにして、 Table does not exist ストリングを OUT_BUFFER 出力パラメーターに置いてから、ハンドラーが宣言された複合ステートメントを終了します。
DECLARE UNDO HANDLER FOR SQLSTATE '42704' BEGIN SET OUT_BUFFER='Table does not exist'; END;
注: | UNDO ハンドラーは ATOMIC 複合ステートメントのみで宣言できます。 |
SIGNAL および RESIGNAL ステートメントを使用して、特定の SQLSTATE を明示的に起こすことができます。 SIGNAL および RESIGNAL ステートメントの SET MESSAGE_TEXT 文節を使用して、カスタム定義された SQLSTATE で DB2 が表示するテキストを定義します。
次の例では、 SQL プロシージャー本体はカスタム SQLSTATE 72822 の条件ハンドラーを宣言します。プロシージャーによって SQLSTATE 72822 を起こす SIGNAL ステートメントが実行される場合、 DB2 は条件ハンドラーを呼び出します。条件ハンドラーは、 SQL 変数 var の値を IF ステートメントでテストします。 var が OK である場合には、ハンドラーは SQLSTATE の値を 72623 に再定義して SQLSTATE 72623 に関連したテキストにストリング・リテラルを割り当てます。 var が OK でない場合には、ハンドラーによって SQLSTATE 値が 72319 に再定義されて、その SQLSTATE に関連したテキストに var 値が割り当てられます。
DECLARE EXIT CONDITION HANDLER FOR SQLSTATE '72822' BEGIN IF ( var = 'OK' ) RESIGNAL '72623' SET MESSAGE_TEXT = 'Got SQLSTATE 72822'; ELSE RESIGNAL '72319' SET MESSAGE_TEXT = var; END; SIGNAL SQLSTATE '72822';
SIGNAL および RESIGNAL ステートメントの詳細については、 SQL 解説書 を参照してください。
SQL プロシージャーをデバッグする助けとして、 SQL プロシージャーの様々な時点で SQLCODE および SQLSTATE の値を表に挿入したり、診断ストリングの OUT パラメーターとして SQLCODE および SQLSTATE の値を戻すのが役に立つかもしれません。 SQLCODE および SQLSTATE 値を使用するには、 SQL プロシージャー本体で以下のような SQL 変数を宣言する必要があります。
DECLARE SQLCODE INTEGER DEFAULT 0; DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
さらに、CONTINUE 条件ハンドラーを使用して、 SQLSTATE および SQLCODE の値を SQL プロシージャー本体のローカル変数に割り当てられます。それから、これらのローカル変数を使用してプロシージャー論理を制御したり、値を出力パラメーターとして戻すことができます。以下の例では、SQL プロシージャーは制御を各 SQL ステートメントに続くステートメントに戻します。 SQLCODE は、RETCODE というローカル変数に設定します。
DECLARE SQLCODE INTEGER DEFAULT 0; DECLARE retcode INTEGER DEFAULT 0; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET retcode = SQLCODE; DECLARE CONTINUE HANDLER FOR SQLWARNING SET retcode = SQLCODE; DECLARE CONTINUE HANDLER FOR NOT FOUND SET retcode = SQLCODE;
注: | SQL プロシージャーで SQLCODE または SQLSTATE 変数をアクセスする場合には、 DB2 によって、後続するステートメントの SQLCODE 値は 0、また SQLSTATE 値は '00000' に設定されます。 |