MySQL では、特定の例外には特定の処理が必要です。これらの例外は、サブルーチン内の一般的なフロー制御だけでなく、エラーにもリンクされている可能性があります。例外の定義とは、プログラムの実行中に発生する問題を事前に定義することです。例外処理は、問題が発生したときに採用する必要がある処理方法を定義し、エラーや警告が発生した場合でもストアド プロシージャや関数が実行を継続できるようにします。
1 例外定義
1.1 構文
DECLARE 条件名 CONDITION FOR
[condition_type];
1.2 説明
condition_name パラメータは例外の名前を表し、condition_type は SQLSTATE で表されます。
[VALUE] sqlstate_value|mysql_error_code は以下で構成されます:
sqlstate_value は長さ 5 の文字列型のエラー コードです。
mysql_error_code は数値型のエラー コードです。
「ERROR」の定義
1148(42000)" エラー、名前は command_not_allowed です。 2 つのメソッドがあります:
//方法一:使用sqlstate_value DECLARE command_not_allowed CONDITION FOR SQLSTATE '42000′; //方法二:使用mysql_error_code DECLARE command_not_allowed CONDITION FOR 1148;
DECLARE handler_type HANDLER FOR condition_value [,...] sp_statement
CONTINUE はエラーを処理せずに実行を継続することを意味します。
EXIT はエラーが発生したときにすぐに終了することを意味します。前の操作を元に戻した後、MySQL はまだロールバック操作をサポートしていません: SQLSTATE [VALUE] sqlstate_value| SQLWARNING|NOT
FOUND|SQLEXCEPTION|mysql_error_code
condition_value はエラーの種類を示します
condition_name は DECLARE を意味します。
CONDITION で定義されたエラー条件名は、
SQLWARNING で始まるすべての SQLSTATE エラー コードと一致します。
FOUND は 02 で始まるすべての SQLSTATE エラー コードに一致します。
mysql_error_code によってキャプチャされた SQLSTATE エラー コードは、値タイプのエラー コードと一致します。例外処理を定義せずに実行されたステップを確認します。
/方法一:捕获sqlstate_value异常 //这种方法是捕获sqlstate_value值。如果遇到sqlstate_value值为”42S02″,执行CONTINUE操作,并输出”NO_SUCH_TABLE”信息 DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02′ SET @info='NO_SUCH_TABLE'; //方法二:捕获mysql_error_code异常 //这种方法是捕获mysql_error_code值。如果遇到mysql_error_code值为1146,执行CONTINUE操作,并输出”NO_SUCH_TABLE”信息; DECLARE CONTINUE HANDLER FOR 1146 SET @info='NO_SUCH_TABLE'; //方法三:先定义条件,然后捕获异常 DECLARE no_such_table CONDITION FOR 1146; DECLARE CONTINUE HANDLER FOR NO_SUCH_TABLE SET @info='NO_SUCH_TABLE'; //方法四:使用SQLWARNING捕获异常 DECLARE EXIT HANDLER FOR SQLWARNING SET @info='ERROR'; //方法五:使用NOT FOUND捕获异常 DECLARE EXIT HANDLER FOR NOT FOUND SET @info='NO_SUCH_TABLE'; //方法六:使用SQLEXCEPTION捕获异常 DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @info='ERROR';
show databases; use wms; create table location ( location_id int primary key, location_name varchar(50) );
DELIMITER // CREATE PROCEDURE handlerInsertNoException() BEGIN /*DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2=1;*/ SET @x=1; INSERT INTO location VALUES (1,'Beijing'); SET @x=2; INSERT INTO location VALUES (1,'Wuxi'); SET @x=3; END; // DELIMITER ;
注: 例 2 を操作する前に、テーブル内のデータをクリアし、ログアウトしてログを記録する必要があります。クライアント変数 @x の影響を回避するために再度入力します。詳細については、結論の最初の点を参照してください。
mysql> call handlerInsertNoException(); ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY' mysql> select @x; +------+ | @x | +------+ | 2 | +------+ 1 row in set (0.00 sec) mysql> select * from location; +-------------+---------------+ | location_id | location_name | +-------------+---------------+ | 1 | Beijing | +-------------+---------------+ 1 row in set (0.00 sec)
mysql> truncate table location; Query OK, 0 rows affected (0.04 sec) mysql> select * from location; Empty set (0.00 sec) mysql> exit; Bye david@Louis:~$ mysql -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 53 Server version: 5.5.38-0ubuntu0.14.04.1 (Ubuntu) mysql> use wms; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> select * from location; Empty set (0.00 sec) mysql> select @x; +------+ | @x | +------+ | NULL | +------+ 1 row in set (0.00 sec)
DELIMITER // CREATE PROCEDURE handlerInsertWithException() BEGIN DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2=1; SET @x=1; INSERT INTO location VALUES (1,'Beijing'); SET @x=2; INSERT INTO location VALUES (1,'Wuxi'); SET @x=3; END; // DELIMITER ;
説明と結論:
1. MySQL では、@var_name はユーザー変数を表し、SET ステートメントを使用します。割り当ての場合、ユーザー変数は接続に関連しています。あるクライアントによって定義された変数は、他のクライアントからは参照または使用できません。クライアントが終了すると、そのクライアント接続のすべての変数が自動的に解放されます。
2. 例 1 では、注釈付きの例外ステートメント「」により、同じ主キーをテーブルに挿入すると例外がトリガーされ、デフォルト (EXIT) パスが使用され、この時点で @x がチェックされて 2 が返されます。
3. この時点でエラーが発生した場合、実行は続行されますが、最初のデータのみが挿入されます。このテーブルは、ユーザー変数 @x=3 が実行が終了したことを示しています。