如何在MySQL函数中引发错误


Answers:



25

它实际上是所有三个答案的组合。您调用一个不存在的过程来引发错误,然后声明一个捕获您所生成的错误的退出处理程序。这是一个示例,如果要删除的行设置了外键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. | 
+----------------------------------------------------+

1
应当注意,这仅适用于存储过程,不适用于函数。在函数中,SELECT处理程序内的会导致有关无法从函数返回集合的神秘错误。
凯夫2012年

仅对一条错误消息有效。实际上,您将需要进行多次验证,并且需要提出不同的错误,但是使用单个退出处理程序可能不是走的路。
Pradeep Puranik

9

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

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

错误信息是:

错误的整数值:第1行的“ ERROR”列的“ something failed”

它不是完美的,但是它给出了一个漂亮的描述性消息,您不必编写任何扩展DLL。


这是非常聪明的。到目前为止,最简单,最清晰的方法。
SystemParadox 2014年

@SystemParadox在必须报告足够的错误之后,找到一种更好的方法变得有些执迷。(首先是它call raise_error_life_sucks();,然后随着我需要的地方逐渐发展,我不能仅仅称之为proc)

@Isblsb,您需要将sql_mode设置为strict_trans_tables才能引发错误。创建函数时,strict_trans_tables必须有效。
弗拉基米尔·斯特鲁加茨基


2

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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.