mysql 存储过程出错_mysql存储过程中的错误处理

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:DECLARE action HANDLER FOR condition_value statement;

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

The actionaccepts 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 SQLSTATEvalue. Or it can be an SQLWARNING, NOTFOUNDor SQLEXCEPTIONcondition, which is shorthand for the class of SQLSTATEvalues. The NOTFOUNDcondition is used for a cursoror  SELECT INTO variable_list statement.

A named condition associated with either a MySQL error code or SQLSTATEvalue.

The statementcould be a simple statement or a compound statement enclosing by the BEGINand ENDkeywords.

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.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.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.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.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: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 articlesand tagstables, 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: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: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.CALL insert_article_tags(1,3);

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

AAffA0nNPuCLAAAAAElFTkSuQmCC

If we change the CONTINUEin the handler declaration to EXIT, we will get only the error message.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.CALL insert_article_tags_2(1,3);

AAffA0nNPuCLAAAAAElFTkSuQmCC

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 SQLSTATEmay map to many MySQL error codes therefore it is less specific. An SQLEXCPETIONor an SQLWARNINGis the shorthand for a class of SQLSTATESvalues so it is the most generic.

Based on the handler precedence’s rules,  MySQL error code handler, SQLSTATEhandler and SQLEXCEPTIONtakes the first, second and third precedence.

Suppose we declare three handlers in the  insert_article_tags_3 stored procedure as follows: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:CALL insert_article_tags_3(1,3);

As you see the MySQL error code handler is called.

AAffA0nNPuCLAAAAAElFTkSuQmCC

Using named error condition

Let’s start with an error handler declaration.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:DECLARE condition_name CONDITION FOR condition_value;

The  condition_value can be a MySQL error code such as 1015 or a SQLSTATEvalue. 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: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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值