MySQL SIGNAL 和 RESIGNAL语句
本文将介绍如何在存储程序中使用SIGNAL和RESIGNAL语句来引发错误条件。
MySQL SIGNAL语句
SIGNAL查询是一种机制,用于在存储程序(如存储过程、触发器或事件或存储函数)执行过程中返回警告或错误消息。该语句向错误处理程序、应用程序的外部部分或客户端提供错误信息。它还提供了对存储过程中的错误特性(如错误编号、SQLSTATE值和消息)的控制。SIGNAL语句在执行过程中不需要任何特权。
语法
使用SIGNAL语句的基本语法如下:
SIGNAL SQLSTATE | condition_name;
SET condition_information_item_name1 = value1,
condition_information_item_name1 = value2, etc;
在这里,由DECLARE CONDITION语句声明的SQLSTATE或condition_name指示要返回的错误值。需要注意的是,SIGNAL语句必须具有SQLSTATE值或使用SQLSTATE值定义的命名条件。
SQLSTATE由五个字母数字字符组成。我们不会使用SQLSTATE代码为’00’,因为它表示成功,而成功对于引发错误是无效的。当值无效时,会发现Bad SQLSTATE错误。如果我们想要捕获所有错误处理,我们必须分配SQLSTATE代码’45000’,这意味着未处理的用户定义异常。
可选的SET子句用于向调用者提供信息。如果需要返回多个条件信息项名称,则需要使用逗号运算符来分隔每个名称/值对。
condition_information_item_name可以是以下任何一种,并且在SET子句中只能指定一次。否则,它将返回重复的条件信息项错误。
- CLASS_ORIGIN
- MESSAGE_TEXT
- MYSQL_ERRNO
- CONSTRAINT_NAME
- SCHEMA_NAME
- TABLE_NAME
- CURSOR_NAME等等
让我们通过一个例子来理解SIGNAL的实现。
例子
这里我们首先创建一个名为addStudent的过程。此过程首先计算具有所传递的输入学生id的总学生人数。其次,它在表中检查它们,如果学生人数不是1,则会返回一个带有SQLSTATE 45000的错误,以及消息学生id不存在于student_info表中。我们会注意到,45000是一个用于未处理的用户定义异常的通用SQLSTATE。
以下是完整的过程代码:
CREATE PROCEDURE addStudent(
IN stud_id INT,
IN stud_name VARCHAR(35),
IN subject VARCHAR(25),
IN marks INT,
IN phone VARCHAR(15)
)
BEGIN
DECLARE C INT;
SELECT COUNT(student_id) INTO C
FROM student_info
WHERE student_id = stud_id;
-- check if student id not exists
IF(C != 1) THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Student id not found in student_info table';
END IF;
END $$
DELIMITER ;
当我们使用提供的学生详细信息调用该程序时,我们将收到一个错误消息。
CALL addStudent (16, 'Kevin', 'science', 66, '69934569359');
这是输出结果:
MySQL RESIGNAL语句
MySQL 提供RESIGNAL语句,用于引发类似于SIGNAL语句的警告或错误条件,其功能和语法方面类似, 只是 :
- RESIGNAL语句必须在错误处理程序或警告处理程序内使用。否则,MySQL会生成错误消息:当处理程序不活动时,RESIGNAL。
- RESIGNAL语句可以不带任何属性使用,甚至不带SQLSTATE值或SIGNAL语句中的属性。
如果我们在存储过程中只使用RESIGNAL语句,那么所有属性都与传递给条件处理程序的属性相同。
例子
让我们通过一个例子来理解,该过程在向调用者发出错误消息之前更改错误消息。
DELIMITER CREATE PROCEDURE getDevision (IN numerator INT, IN denominator INT, OUT res double)
BEGIN
DECLARE Division_By_Zero CONDITION FOR SQLSTATE '45000';
DECLARE CONTINUE HANDLER FOR Division_By_Zero RESIGNAL SET MESSAGE_TEXT = 'The denominator cannot be zero';
-- IF denominator = 0 THEN
SIGNAL Division_By_Zero;
ELSE
SET res := numerator / denominator;
END IF;
END
DELIMITER ;
如果我们使用以下语句调用过程,将会收到一个错误消息:
CALL getDivision (25, 0, @res);
这是结果: