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

When an error occurs inside a stored procedure, it is important to handle it appropriately, such as continuing or exiting the current code block’s execution, and issuing a meaningful error message.

MySQL provides an easy way to define handlers that handle from general conditions such as warnings or exceptions to specific conditions e.g., specific error codes.

Declaring a handler

To declare a handler, you use the  DECLARE HANDLER statement as follows:

 
1
DECLARE action HANDLER FOR condition_value statement;

If a condition whose value matches the  condition_value, MySQL will execute the statement and continue or exit the current code block based on the action.

The action accepts one of the following values:

  • CONTINUE:  the execution of the enclosing code block ( BEGIN … END) continues.
  • EXIT: the execution of the enclosing code block, where the handler is declared, terminates.

The  condition_value specifies a particular condition or a class of conditions that activates the handler. The  condition_value accepts one of the following values:

  • A MySQL error code.
  • A standard SQLSTATE value. Or it can be an SQLWARNINGNOTFOUND or SQLEXCEPTIONcondition, which is shorthand for the class of SQLSTATE values. The NOTFOUND condition is used for a cursoror  SELECT INTO variable_list statement.
  • A named condition associated with either a MySQL error code or SQLSTATE value.

The statement could be a simple statement or a compound statement enclosing by the BEGIN andEND keywords.

MySQL error handling examples

Let’s look into several examples of declaring handlers.

The following handler means if an error occurs, set the value of the  has_error variable to 1 and continue the execution.

 
1
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET has_error = 1;

The following is another handler; it means that in case any error occurs, rollback the previous operation, issue an error message and exit the current code block. If you declare it inside the   BEGIN END block of a stored procedure, it will terminate stored procedure immediately.

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

If there are no more rows to fetch, in case of a cursoror SELECT INTOstatement, set the value of the no_row_found variable to 1 and continue execution.

 
1
DECLARE CONTINUE HANDLER FOR NOT FOUND SET no_row_found = 1;

If a duplicate key error occurs, MySQL error 1062 is issued. The following handler issues an error message and continues execution.

 
1
2
DECLARE CONTINUE HANDLER FOR 1062
SELECT 'Error, duplicate key occurred';

MySQL handler example in stored procedures

First, we create a new table named  article_tags for the demonstration:

 
1
2
3
4
5
CREATE TABLE article_tags(
    article_id INT,
    tag_id     INT,
    PRIMARY KEY(article_id,tag_id)
);

The  article_tags table stores the relationships between articles and tags. Each article may have many tags and vice versa. For the sake of simplicity, we don’t create articles and tags tables, as well as the foreign keys in the  article_tags table.

Second, we create a stored procedure that inserts a pair of ids of article and tag into the article_tags table:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

Third, we add tag id 1, 2 and 3 for the article 1 by calling the  insert_article_tags stored procedure as follows:

 
1
2
3
CALL insert_article_tags(1,1);
CALL insert_article_tags(1,2);
CALL insert_article_tags(1,3);

Fourth, let’s try to insert a duplicate key to see if the handler is really invoked.

 
1
CALL insert_article_tags(1,3);

We got an error message. However, because we declared the handler as a CONTINUE handler, the stored procedure continued execution. As the result, we got the tag count for the article as well.

If we change the CONTINUE in the handler declaration to EXIT, we will get only the error message.

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
DELIMITER $$
 
CREATE PROCEDURE insert_article_tags_2(IN article_id INT, IN tag_id INT)
BEGIN
 
DECLARE EXIT HANDLER FOR SQLEXCEPTION
SELECT 'SQLException invoked';
 
DECLARE EXIT HANDLER FOR 1062
        SELECT 'MySQL error code 1062 invoked';
 
DECLARE EXIT HANDLER FOR SQLSTATE '23000'
SELECT 'SQLSTATE 23000 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

Now, we can try to add a duplicate key to see the effect.

 
1
CALL insert_article_tags_2(1,3);

MySQL handler precedence

In case there are multiple handlers that are eligible for handling an error, MySQL will call the most specific handler to handle the error.

An error always maps to one MySQL error code so a MySQL it is the most specific. An SQLSTATE may map to many MySQL error codes therefore it is less specific. An SQLEXCPETION or an SQLWARNINGis the shorthand for a class of SQLSTATES values so it is the most generic.

Based on the handler precedence’s rules,  MySQL error code handler, SQLSTATE handler andSQLEXCEPTION takes the first, second and third precedence.

Suppose we declare three handlers in the  insert_article_tags_3 stored procedure as follows:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
DELIMITER $$
 
CREATE PROCEDURE insert_article_tags_3(IN article_id INT, IN tag_id INT)
BEGIN
 
DECLARE EXIT HANDLER FOR 1062 SELECT 'Duplicate keys error encountered';
DECLARE EXIT HANDLER FOR SQLEXCEPTION SELECT 'SQLException encountered';
DECLARE EXIT HANDLER FOR SQLSTATE '23000' SELECT 'SQLSTATE 23000';
 
-- 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

We now try to insert a duplicate key into the article_tags table by calling the stored procedure:

 
1
CALL insert_article_tags_3(1,3);

As you see the MySQL error code handler is called.

Using named error condition

Let’s start with an error handler declaration.

 
1
2
DECLARE EXIT HANDLER FOR 1051 SELECT 'Please create table abc first';
SELECT * FROM abc;

What does the number 1051 really mean? Imagine you have a big stored procedure polluted with those numbers all over places; it will become a nightmare for the maintenance developers.

Fortunately, MySQL provides us with the  DECLARE CONDITION statement that declares a named error condition, which associates with a condition. The syntax of the  DECLARE CONDITION statement is as follows:

 
1
DECLARE condition_name CONDITION FOR condition_value;

The  condition_value can be a MySQL error code such as 1015 or a SQLSTATE value. The condition_value is represented by the condition_name.

After declaration, you can refer to the  condition_name instead of the condition_value.

So we can rewrite the code above as follows:

 
1
2
3
DECLARE table_not_found CONDITION for 1051;
DECLARE EXIT HANDLER FOR  table_not_found SELECT 'Please create table abc first';
SELECT * FROM abc;

This code is obviously more readable than the previous one.

Notice that the condition declaration must appear before handler or cursor declarations.

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

MySQL Error Handling 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

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

  3. mysql Error Handling and Raising in Stored Procedures

    MySQL的存储过程错误捕获方式和Oracle的有很大的不同. MySQL中可以使用DECLARE关键字来定义处理程序.其基本语法如下: DECLARE handler_type HANDLER FO ...

  4. Spring MVC-表单(Form)标签-错误处理(Error Handling)示例(转载实践)

    以下内容翻译自:https://www.tutorialspoint.com/springmvc/springmvc_errors.htm 说明:示例基于Spring MVC 4.1.6. 以下示例显 ...

  5. An Introduction to Stored Procedures in MySQL 5

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

  6. [MySQL] Stored Procedures 【转载】

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

  7. 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 ...

  8. Cursors in MySQL Stored Procedures

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

  9. 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 ...

随机推荐

  1. 如何删除github上的项目

    如果大伙用过github,那么就会知道它上面没有明显的选项可以让你直接删除掉一个Repositories或者项目.因此对很多github的新手来说一开始也常觉得这个事情比较犯难.这里我给大家简单介绍一 ...

  2. Django如何设置proxy

    设置porxy的原因 一般情况下我们代理设置是针对与浏览器而言,通常只需在浏览器设置中进行配置,但它只针对浏览器有效,对我们自己编写的程序并任何效果,这时就需要我们在软件编码中加入代理设置. --- ...

  3. 为何要fork()两次来避免产生僵尸进程??

    最近安装书上说的,开始搞多进程了..看到了一个好帖子,学习学习 http://blog.sina.com.cn/s/blog_9f1496990100y420.html 首先我们要明白,为什么要避免僵 ...

  4. HDU 5726 GCD (2016 Multi-University Training Contest 1)

      Time Limit: 5000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u Description Give y ...

  5. chrome:// 的秘密!!一些有用的命令!

    chrome:// .......命令 集结 Chrome 有很多的特性在界面菜单中是没有体现的,可以通过 chrome:// 命令来访问 我搜集了下面这些!!!当然也是在网上找的!有的我自己也不知道 ...

  6. python 模块导入

    1. 模块导入: 要使用一个模块,我们必须首先导入该模块.Python使用import语句导入一个模块.例如,导入系统自带的模块 math: import math 你可以认为math就是一个指向已导 ...

  7. jQuery中的data方法:

    向元素附加数据,然后取回该数据: $("#btn1").click(function(){ $("div").data("greeting" ...

  8. BZOJ 4008 亚瑟王

    Description 小K不慎被LL邪教洗脑了,洗脑程度深到他甚至想要从亚瑟王邪教中脱坑. 他决定,在脱坑之前,最后再来打一盘亚瑟王.既然是最后一战,就一定要打得漂亮.众所周知,亚瑟王是一个看脸的游 ...

  9. [BZOJ 1082] [SCOI2005] 栅栏 【二分 + DFS验证(有效剪枝)】

    题目链接:BZOJ - 1082 题目分析 二分 + DFS验证. 二分到一个 mid ,验证能否选 mid 个根木棍,显然要选最小的 mid 根. 使用 DFS 验证,因为贪心地想一下,要尽量先用提 ...

  10. Ubuntu 12安装Virtualbox

    用aptitude或者apt-get安装Virtualbox,安装过程中会报:”No suitable module for running kernel found [fail]“,安装未成功. 在 ...