MySQL SIGNAL和RESIGNAL
本文将介绍如何使用 SIGNAL 和 RESIGNAL 语句在存储程序中引发错误条件。
一、MySQL SIGNAL 语句
SIGNAL 查询是一种用于返回在存储程序(例如存储过程、触发器或事件或存储函数)执行期间出现的警告或错误消息的机制。此语句向错误处理程序、应用程序的外部部分或客户端提供错误信息。它还提供对错误特征的控制,例如存储过程中的错误号、SQLSTATE、值和消息。SIGNAL 语句的执行不需要任何特权。
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 由五个字母数字字符组成。我们不使用带有'00'的 SQLSTATE 代码,因为它表示成功,这对于引发错误无效。值无效时发现 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 的实现。
SIGNAL 示例
在这里,我们将首先创建一个名为addStudent的过程。此过程首先计算具有我们在存储过程中传递的输入学生 id的学生总数。其次,它在表中检查它们,如果学生数不是 1,它将返回 SQLSTATE 45000 的错误以及消息student id does not exist in the student_info table。我们会注意到 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 语句可以在没有任何属性的情况下使用,即使是在 SIGNAL 语句中的 SQLSTATE 值或属性。
如果我们在存储程序中只使用 RESIGNAL 语句,所有属性都与传递给条件处理程序的属性相同。
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);
结果如下:
热门文章
优秀文章