条件とハンドラ

1. DECLARE 条件
2. DECLARE ハンドラ

条件によっては、特別な扱いが求められます。これらの条件は、エラー並びにルーチンの内側で行われている一般フロー制御に関連している場合もあります。

1. DECLARE 条件

DECLARE condition_name CONDITION FOR condition_value

condition_value:
    SQLSTATE [VALUE] sqlstate_value
  | mysql_error_code

このステートメントは特別な扱いが必要な条件を規定します。それには規定されたエラーの条件を含む名称が関連付けられます。その名称は後にDECLARE HANDLERステートメントの中で使われます。項2. 「DECLARE ハンドラ」 を参照してください。

condition_valueをSQLSTATE値もしくはMySQLエラーコードにすることができます。

2. DECLARE ハンドラ

DECLARE handler_type HANDLER FOR condition_value[,...] statement

handler_type:
    CONTINUE
  | EXIT
  | UNDO

condition_value:
    SQLSTATE [VALUE] sqlstate_value
  | condition_name
  | SQLWARNING
  | NOT FOUND
  | SQLEXCEPTION
  | mysql_error_code

DECLARE ... HANDLERステートメントは各々が複数の条件で処理することができるハンドラを規定します。もし、これらの条件の1つが起った場合、ステートメントが実行されます。この場合、ステートメントを単純なものにすることができます。 (例えば、 SET var_name = value), もしくは、BEGINEND を使って書いた複合ステートメントにすることができます。(項 「BEGIN ... END 複合ステートメント構文」参照)

CONTINUEハンドラに対して、現ルーチンの実行が、ハンドラステートメントの実行の後に続きます。EXIT ハンドラに関しては、ハンドラが宣言された BEGIN ... END コンパウンドステートメントの中で実行が終了します。(これは、条件が内側にあるブロックの中に発生する場合でも同じです。)UNDO ハンドラタイプのステートメントはまだサポートされていません。

ハンドラがまだ宣言されていない条件がしている場合、デフォルトアクションはEXITとなります。

A condition_valueは以下の値のいずれかにすることができます:

  • SQLSTATE値もしくはMySQLエラーコード。

  • 既に DECLARE ... CONDITIONで指定されている条件名。項1. 「DECLARE 条件」 を参照してください。

  • SQLWARNING01で始まる全てのSQLSTATEコードに対する速記文字です。

  • NOT FOUND02で始まる全てのSQLSTATEコードに対する速記文字です。

  • SQLEXCEPTIONSQLWARNINGまたはNOT FOUNDによって捕らえられなかった全てのSQLSTATEコードの速記文字です。

例:

mysql> CREATE TABLE test.t (s1 int,primary key (s1));
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter //

mysql> CREATE PROCEDURE handlerdemo ()
    -> BEGIN
    ->   DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1;
    ->   SET @x = 1;
    ->   INSERT INTO test.t VALUES (1);
    ->   SET @x = 2;
    ->   INSERT INTO test.t VALUES (1);
    ->   SET @x = 3;
    -> END;
    -> //
Query OK, 0 rows affected (0.00 sec)

mysql> CALL handlerdemo()//
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @x//
    +------+
    | @x   |
    +------+
    | 3    |
    +------+
    1 row in set (0.00 sec)

その例は、重複キーエラーに対して発生するSQLSTATE 23000を持つハンドラに関連するものです。@x は 3です。 MySQLがプロシージャの最後まで実行されたことを示しています。もしDECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1;ラインが存在していなかった場合、 MySQLは(EXIT) のデフォルトパスを、2番目のINSERTPRIMARY KEY制限によって失敗したとき取り、そしてSELECT @x2を返しています。

条件を無視したい場合、ユーザはそれに対して、CONTINUEハンドラと宣言して、それを空のブロックと関連させることができます。例:

DECLARE CONTINUE HANDLER FOR SQLWARNING BEGIN END;