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

结果如下:

热门文章

优秀文章