欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

mysql存储过程之引发存储过程中的错误条件(SIGNAL和RESIGNAL语句)实例分析

程序员文章站 2022-06-07 23:04:02
本文实例讲述了mysql引发存储过程中的错误条件(signal和resignal语句)。分享给大家供大家参考,具体如下: 在mysql中,我们可以使用signal和resignal语...

本文实例讲述了mysql引发存储过程中的错误条件(signal和resignal语句)。分享给大家供大家参考,具体如下:

在mysql中,我们可以使用signal和resignal语句来引发存储过程中的错误条件。

先来看,signal语句。我们通常使用signal语句在存储的程序(例如存储过程,存储函数,触发器或事件)中向调用者返回错误或警告条件。 signal语句提供了对返回值(如值和消息sqlstate)的信息的控制。来看下它的语法结构:

signal sqlstate | condition_name;
set condition_information_item_name_1 = value_1,
  condition_information_item_name_1 = value_2, etc;

signal关键字是由declare condition语句声明的sqlstate值或条件名称。不过要注意的是,signal语句必须始终指定使用sqlstate值定义的sqlstate值或命名条件。完事我们如果要向调用者提供信息,就得使用set子句,如果要使用值返回多个条件信息项名称,则需要用逗号分隔每个名称/值对。上述sql中,condition_information_item_name可以是message_text,mysql_errorno,cursor_name等。咱们来看一个将订单行项目添加到现有销售订单中的存储过程,如果订单号码不存在,它会发出错误消息:

delimiter $$
create procedure addorderitem(in orderno int,
 in productcode varchar(45),
 in qty int,in price double, in lineno int )
begin
 declare c int;
 select count(ordernumber) into c
 from orders 
 where ordernumber = orderno;
 -- check if ordernumber exists
 if(c != 1) then 
 signal sqlstate '45000'
 set message_text = 'order no not found in orders table';
 end if;
 -- more code below
 -- ...
end $$
delimiter ;

一开始,它使用传递给存储过程的输入订单号对订单进行计数,完事如果订单数不是1,它会引发sqlstate 45000的错误以及orders表中不存在订单号的错误消息。其中45000是一个通用sqlstate值,用于说明未处理的用户定义异常。

我们来调用存储过程addorderitem(),但是传递不存在的订单号,那么将收到一条错误消息:

call addorderitem(10,'s10_1678',1,95.7,1);

执行上面代码,得到以下结果:

mysql> call addorderitem(10,'s10_1678',1,95.7,1);
1644 - order no not found in orders table
mysql>

咱们再来看resignal语句。它在功能和语法方面与signal语句相似,只是有以下区别:

  • 必须在错误或警告处理程序中使用resignal语句,否则您将收到一条错误消息,指出“resignal when handler is not active”。 请注意,您可以在存储过程中的任何位置使用signal语句。
  • 可以省略resignal语句的所有属性,甚至可以省略sqlstate值。

如果单独使用resignal语句,则所有属性与传递给条件处理程序的属性相同。咱们来看一个在将发送给调用者之前更改错误消息的存储过程:

delimiter $$
create procedure divide(in numerator int, in denominator int, out result double)
begin
 declare division_by_zero condition for sqlstate '22012';
 declare continue handler for division_by_zero 
 resignal set message_text = 'division by zero / denominator cannot be zero';
 -- 
 if denominator = 0 then
 signal division_by_zero;
 else
 set result := numerator / denominator;
 end if;
end $$
delimiter ;

然后,我们来尝试调用:

mysql> call divide(10,0,@result);
1644 - division by zero / denominator cannot be zero

好啦,本次记录就到这里了,不知道大家有没有什么收获。