MySQL的存储过程错误捕获方式和Oracle的有很大的不同。

MySQL中可以使用DECLARE关键字来定义处理程序。其基本语法如下:

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

handler_type: CONTINUE | EXIT  

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

handler_type参数指明错误的处理方式,该参数有2个取值。这1个取值分别是CONTINUE、EXIT

CONTINUE表示遇到错误,执行预先定义的方式,继续向下执行;

EXIT表示遇到错误后,执行预先定义的方式,马上退出;

注意:通常情况下,执行过程中遇到错误应该立刻停止执行下面的语句,并且撤回前面的操作。

condition_value参数指明错误类型,该参数有6个取值。

sqlstate_value和mysql_error_code与条件定义中的是同一个意思。

condition_name是DECLARE定义的条件名称。

SQLWARNING表示所有以01开头的sqlstate_value值。

NOT FOUND表示所有以02开头的sqlstate_value值。

SQLEXCEPTION表示所有没有被SQLWARNING或NOT FOUND捕获的sqlstate_value值。

sp_statement表示一些存储过程或函数的执行语句。

下面是定义处理程序的几种方式。代码如下:

//方法一:捕获sqlstate_value
DECLARE CONTINUE HANDLER FOR SQLSTATE ''
SET @info='CAN NOT FIND';
//方法二:捕获mysql_error_code
DECLARE CONTINUE HANDLER FOR 1148SET @info='CAN NOT FIND';
//方法三:先定义条件,然后调用
DECLARE can_not_find CONDITION FOR 1146 ;
DECLARE CONTINUE HANDLER FOR can_not_find SET
@info='CAN NOT FIND';
//方法四:使用SQLWARNING
DECLARE EXIT HANDLER FOR SQLWARNING SET @info='ERROR';
//方法五:使用NOT FOUND
DECLARE EXIT HANDLER FOR NOT FOUND SET @info='CAN NOT FIND';
//方法六:使用SQLEXCEPTION
DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @info='ERROR';

上述代码是6种定义处理程序的方法。

第一种方法是捕获sqlstate_value值。如果遇到sqlstate_value值为42000,执行CONTINUE操作,并且输出"CAN NOT FIND"信息。

第二种方法是捕获mysql_error_code值。如果遇到mysql_error_code值为1148,执行CONTINUE操作,并且输出"CAN NOT FIND"信息。

第三种方法是先定义条件,然后再调用条件。这里先定义can_not_find条件,遇到1148错误就执行CONTINUE操作。

第四种方法是使用SQLWARNING。SQLWARNING捕获所有以01开头的sqlstate_value值,然后执行EXIT操作,并且输出"ERROR"信息。

第五种方法是使用NOT FOUND。NOT FOUND捕获所有以02开头的sqlstate_value值,然后执行EXIT操作,并且输出"CAN NOT FIND"信息。

第六种方法是使用SQLEXCEPTION。SQLEXCEPTION捕获所有没有被SQLWARNING或NOT FOUND捕获的sqlstate_value值。

单句的

DECLARE CONTINUE HANDLER FOR NOT FOUND SET no_row_found = 1;
DECLARE CONTINUE HANDLER FOR 1062
SELECT 'Error, duplicate key occurred';

如果错误捕获的时候要做的操作比较多可以这样

DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
SELECT 'An error has occurred, operation rollbacked and the stored procedure was terminated';
END;

example:

CREATE TABLE `article_tags` (
`article_id` int(11) NOT NULL DEFAULT '',
`tag_id` int(11) NOT NULL DEFAULT '',
PRIMARY KEY (`article_id`,`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DELIMITER $$

CREATE PROCEDURE insert_article_tags(IN article_id INT, IN tag_id INT)
BEGIN DECLARE CONTINUE HANDLER FOR 1062
SELECT CONCAT('duplicate keys (',article_id,',',tag_id,') found') AS msg; -- insert a new record into article_tags
INSERT INTO article_tags(article_id,tag_id)
VALUES(article_id,tag_id); -- return tag count for the article
SELECT COUNT(*) FROM article_tags;
END

mysql 抛出错误给调用程序

使用signal语句返回Error或warning给存储过程的调用者。

signal的语法:

SIGNAL SQLSTATE | condition_name
SET condition_information_item_name_1 = value_1,
condition_information_item_name_1 = value_2, etc;

使用SET设置返回的内容,如果要返回多个条件信息用逗号隔开。

RESIGNAL无论是功能上还是用法上和signal都很像,除了:

  1.使用resignal的时候必须配合handler使用,否则会得到 “RESIGNAL when handler is not active”的报错,

然而signal可以在存储过程的任何地方使用。

  2.可以漏掉resignal语句的所有属性,甚至是SQLSTATE value.

DELIMITER $$

CREATE PROCEDURE AddOrderItem(
in orderNo int,
in productCode varchar(45),
in qty int,
in price double,
in lineNo int )
BEGIN
DECLARE C INT; SELECT COUNT(orderNumber) INTO C
FROM orders
WHERE orderNumber = orderNo; -- check if orderNumber exists
IF(C != 1) THEN
SIGNAL SQLSTATE ''
SET MESSAGE_TEXT = 'Order No not found in orders table';
END IF;
-- more code below
-- ...
END
DELIMITER $$

CREATE PROCEDURE Divide(IN numerator INT, IN denominator INT, OUT result double)
BEGIN
DECLARE division_by_zero CONDITION FOR SQLSTATE ''; DECLARE CONTINUE HANDLER FOR division_by_zero
RESIGNAL SET MESSAGE_TEXT = 'Division by zero / Denominator cannot be zero';
--
IF denominator = 0 THEN
SIGNAL division_by_zero;
ELSE
SET result := numerator / denominator;
END IF;
END

没有resignal 的时候调用存储过程:

DELIMITER $$

CREATE DEFINER=`root`@`localhost` PROCEDURE `insert_article_tags`(IN article_id INT, IN tag_id INT)
BEGIN DECLARE CONTINUE HANDLER FOR 1062
begin
insert into pro_log values('',CONCAT('duplicate keys (',article_id,',',tag_id,') found'));
SELECT CONCAT('duplicate keys (',article_id,',',tag_id,') found') AS msg;
-- resignal set message_text ='duplicate keys';
end ; -- declare continue handler for sqlexception
-- SELECT 'SQLException invoked'; -- insert a new record into article_tags
INSERT INTO article_tags(article_id,tag_id)
VALUES(article_id,tag_id); -- return tag count for the article
SELECT
COUNT(*)
FROM
article_tags; END

测试调用

去掉注释的 resignal set。

继续测试

这样可以得到向外抛出的错误。

参考:

http://www.mysqltutorial.org/mysql-error-handling-in-stored-procedures/

http://www.mysqltutorial.org/mysql-signal-resignal/

http://www.cnblogs.com/lyhabc/p/3793524.html

http://www.zhdba.com/mysqlops/2013/08/31/mysql-handler-2/

mysql Error Handling and Raising in Stored Procedures的更多相关文章

  1. MySQL Error Handling in Stored Procedures 2

    Summary: this tutorial shows you how to use MySQL handler to handle exceptions or errors encountered ...

  2. MySQL Error Handling in Stored Procedures---转载

    This tutorial shows you how to use MySQL handler to handle exceptions or errors encountered in store ...

  3. MySQL Error Handling in Stored Procedures

    http://www.mysqltutorial.org/mysql-error-handling-in-stored-procedures/ mysql存储过程中的异常处理   定义异常捕获类型及处 ...

  4. An Introduction to Stored Procedures in MySQL 5

    https://code.tutsplus.com/articles/an-introduction-to-stored-procedures-in-mysql-5--net-17843 MySQL ...

  5. Home / Python MySQL Tutorial / Calling MySQL Stored Procedures in Python Calling MySQL Stored Procedures in Python

    f you are not familiar with MySQL stored procedures or want to review it as a refresher, you can fol ...

  6. Cursors in MySQL Stored Procedures

    https://www.sitepoint.com/cursors-mysql-stored-procedures/ After my previous article on Stored Proce ...

  7. [MySQL] Stored Procedures 【转载】

    Stored routines (procedures and functions) can be particularly useful in certain situations: When mu ...

  8. MySql Error: Can't update table in stored function/trigger

    MySql Error: Can't update table in stored function/trigger because it is already used by statement w ...

  9. Good Practices to Write Stored Procedures in SQL Server

    Reference to: http://www.c-sharpcorner.com/UploadFile/skumaar_mca/good-practices-to-write-the-stored ...

随机推荐

  1. C++ stringstream介绍,使用方法与例子

    From: http://www.usidcbbs.com/read-htm-tid-1898.html C++引入了ostringstream.istringstream.stringstream这 ...

  2. 六、Socket之UDP异步传输文件-实现稳定的文件传输

    上一篇文章五.Socket之UDP异步传输文件-实现传输中取消传送中,还遗留了一个传输文件最大的问题,就是传输过程中丢包,这样在文件传输过程中就会卡住了,这篇文章就来解决文件传输中的丢包问题,实现稳定 ...

  3. CCCatmullRomTo&CCCatmullRomBy

    注: 云形线(Catmull-Rom curve曲线) 云线(Spline或B-spline)在数学上有很多种类,常用的三阶云线有Hermite, Bezier, Uniform B-spline, ...

  4. iOS 常见知识点(三):Lock

    iOS 常见知识点(一):Runtime iOS 常见知识点(二):RunLoop 锁是最常用的同步工具.一段代码段在同一个时间只能允许被有限个线程访问,比如一个线程 A 进入需要保护代码之前添加简单 ...

  5. 对JavaScript对象数组按指定属性和排序方向进行排序

    引子 在以数据为中心的信息系统中,以表格形式展示数据是在常见不过的方式了.对数据进行排序是必不可少的功能.排序可以分为按单个字段排序和按多个字段不同排序方向排序.单字段排序局限性较大,不能满足用户对数 ...

  6. 一段JavaScript代码

    eval(function(p, a, c, k, e, d) { e = function(c) { return c.toString(36) }; if (!''.replace(/^/, St ...

  7. linux服务器上apache+php独立于mysql server单独部署

    1. mysql client 2. libmysqlclient-devel 3. PDO_MYSQL

  8. 对springMVC的简单理解

    spring框架以及MVC思想: 一:spring框架:spring框架是一种很优秀的框架,它可以帮助开发人员简化组件与组件之间耦合,管理对象.1:创建对象和管理对象之间的关系,可以在配置文件通过be ...

  9. List集合即其遍历

    1. 首先List<E>集合继承与Collection<E>,是一个接口. ①  Collection (集合框架是JDK1.2版本出现的) ②   list:是有序的,元素可 ...

  10. 月半小夜曲下的畅想--DOCTYPE模式

    月半小夜曲下的畅想--DOCTYPE模式 @(css3 box-sizing)[doctype声明|quirks模式|妙瞳] DOCTYPE文档类型标签,该标签是将特定的标准通用标记语言或者XML文档 ...