MySQL 5.5新增SIGNAL異常處理
MySQL 從 5.0 開始支持存儲過程,到現在最新版本5.5 已經好幾個年頭了。 雖然MYSQL的異常處理不是很完善,但是處理大多數的應用還是足夠了。
www.2cto.com
異常處理的語句有如下幾種:
1. DECLARE ... CONDITION.
2. DECLARE ... HANDLER.
3. RESIGNAL.
4. SIGNAL.
第一種,名為條件聲明。
DECLARE condition_name CONDITION FOR condition_value
這裡condition_name 為標准的變量命名, condition_value 為SQLSTATE 值 或者 MySQL 自身的ERROR CODE.
單獨的condition 語句不能直接運行。 只能作為第二種的一部分。
www.2cto.com
第二種, 名為條件處理。
第一種聲明好了,接下來自然要做相應的處理。
DECLARE handler_action HANDLER
FOR condition_value [, condition_value] ...
statement
handler_action:
CONTINUE
| EXIT
| UNDO
condition_value:
mysql_error_code
| SQLSTATE [VALUE] sqlstate_value
| condition_name
| SQLWARNING
| NOT FOUND
| SQLEXCEPTION
handler_action 代表處理的動作,目前有效的有兩種, 繼續和直接退出。
condition_value 有好幾種,其中包括前面條件聲明裡的SQLSTATE, MYSQL EEROR CODE, condition_name 以及范圍混淆的其他兩種
SQLWARNING,SQLEXCEPTION. NOT FOUND表示任何不存在的WARNING或者ERROR。
第三種, 代表偽裝系統的錯誤信息以及代碼,刷新當前警告緩沖區域。
RESIGNAL [condition_value]
[SET signal_information_item
[, signal_information_item] ...]
condition_value:
SQLSTATE [VALUE] sqlstate_value
| condition_name
signal_information_item:
condition_information_item_name = simple_value_specification
condition_information_item_name:
CLASS_ORIGIN
| SUBCLASS_ORIGIN
| MESSAGE_TEXT
| MYSQL_ERRNO
| CONSTRAINT_CATALOG
| CONSTRAINT_SCHEMA
| CONSTRAINT_NAME
| CATALOG_NAME
| SCHEMA_NAME
| TABLE_NAME
| COLUMN_NAME
| CURSOR_NAME
特別注意的是可以偽裝的具體東西很多,包括錯誤代碼(MYSQL自身的東東),錯誤內容,錯誤的數據庫名,表名,列名等等。
第四種,SIGNAL和RESIGNAL差別不大,我們記住signal 不能單獨運行,resignal可以單獨運行。
SIGNAL condition_value
[SET signal_information_item
[, signal_information_item] ...]
condition_value:
SQLSTATE [VALUE] sqlstate_value
| condition_name
signal_information_item:
condition_information_item_name = simple_value_specification
condition_information_item_name:
CLASS_ORIGIN
| SUBCLASS_ORIGIN
| MESSAGE_TEXT
| MYSQL_ERRNO
| CONSTRAINT_CATALOG
| CONSTRAINT_SCHEMA
| CONSTRAINT_NAME
| CATALOG_NAME
| SCHEMA_NAME
| TABLE_NAME
| COLUMN_NAME
| CURSOR_NAME
我們現在給幾個例子。
不用RESIGNAL/SIGNAL。
[sql]
DELIMITER $$
USE `t_girl`$$
DROP PROCEDURE IF EXISTS `sp_signal1`$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_signal1`(
IN f_id INT
)
BEGIN
DECLARE con1 TINYINT DEFAULT 0;
DECLARE con1 CONDITION FOR SQLSTATE '23000';
DECLARE CONTINUE HANDLER FOR con1
BEGIN
SELECT 'Error Code : 22\r\nDuplicated!';
END;
INSERT INTO user_info VALUES (f_id);
END$$
DELIMITER ;
CALL sp_signal1(12);
query result
result
Error Code : 22
Duplicated!
用RESIGNAL/SIGNAL 重刷當前錯誤診斷區域。
[sql]
DELIMITER $$
www.2cto.com
USE `t_girl`$$
DROP PROCEDURE IF EXISTS `sp_signal1`$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_signal1`(
IN f_id INT
)
BEGIN
DECLARE con1 TINYINT DEFAULT 0;
DECLARE con1 CONDITION FOR SQLSTATE '23000';
DECLARE CONTINUE HANDLER FOR con1
BEGIN
resignal SET schema_name = 'action',
table_name = 'action_tb',
message_text = 'Duplicated!',
mysql_errno = 22;
/*
signal con1 SET schema_name = 'action',
table_name = 'action_tb',
message_text = 'Duplicated!',
mysql_errno = 22;
www.2cto.com
*/
END;
INSERT INTO user_info VALUES (f_id);
END$$
DELIMITER ;
CALL sp_signal1(12);
www.2cto.com
Query : call sp_signal1(12)
Error Code : 22
Duplicated!
Execution Time : 00:00:00:000
Transfer Time : 00:00:00:000
Total Time : 00:00:00:000
作者 四爺