MySQL SIGNAL 和 RESIGNAL语句

2024年10月21日 MySQL SIGNAL RESIGNAL语句 极客笔记

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);

这是结果:

本文链接:http://so.lmcjl.com/news/15874/

展开阅读全文