如何在 MySQL 函数中引发错误

我已经创建了一个 MySQL 函数,如果为参数传递的值无效,那么将引发一个错误。在 MySQL 函数中引发错误的选项是什么?

99447 次浏览

您必须定义异常处理程序

在 MySQL 5中,您可能通过调用不存在的存储过程(CALL rise _ error)或向查询传递无效值(如 NULL 到 NOT NULL 约束字段)来引发错误。下面是 Roland Bouman 关于从 MySQL 函数中提取错误的一篇有趣的文章:

Http://rpbouman.blogspot.com/2005/11/using-udf-to-raise-errors-from-inside.html

还可以使用无效数量的参数调用现有函数。

实际上是三个答案的组合。您调用一个不存在的过程来引发错误,然后声明一个出口处理程序来捕获您生成的错误。下面是一个示例,如果要删除的行设置了外键 id,则使用 SQLSTATE 42000(过程不存在)在删除前抛出错误:

DROP PROCEDURE IF EXISTS decount_test;


DELIMITER //


CREATE DEFINER = 'root'@'localhost' PROCEDURE decount_test ( p_id bigint )
DETERMINISTIC MODIFIES SQL DATA
BEGIN
DECLARE EXIT HANDLER FOR SQLSTATE '42000'
SELECT 'Invoiced barcodes may not have accounting removed.';
IF (SELECT invoice_id
FROM accounted_barcodes
WHERE id = p_id
) THEN
CALL raise_error;
END IF;
DELETE FROM accounted_barcodes WHERE id = p_id;
END //


DELIMITER ;

产出:

call decount_test(123456);
+----------------------------------------------------+
| Invoiced barcodes may not have accounting removed. |
+----------------------------------------------------+
| Invoiced barcodes may not have accounting removed. |
+----------------------------------------------------+

MySQL 5.5引入了信号,类似于其他语言中的异常:

Http://dev.mysql.com/doc/refman/5.5/en/signal.html

例如,在 mysql命令行客户端:

mysql> SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Custom error';
ERROR 1644 (45000): Custom error

为什么不在声明的 INTEGER变量中存储 VARCHAR呢?

DELIMITER $$ DROP FUNCTION IF EXISTS `raise_error` $$
CREATE FUNCTION `raise_error`(MESSAGE VARCHAR(255))
RETURNS INTEGER DETERMINISTIC BEGIN
DECLARE ERROR INTEGER;
set ERROR := MESSAGE;
RETURN 0;
END $$ DELIMITER ;
-- set @foo := raise_error('something failed'); -- or within a query

错误信息是:

不正确的整数值: 行中的“ ERROR”列的“有些东西失败了” 1

它并不完美,但是它提供了一个非常具有描述性的消息,而且您不必编写任何扩展 DLL。