MySQL signal和esignal語句

在本教學中,您將學習如何使用SIGNALRESIGNAL語句來引發存儲過程中的錯誤條件。

MySQL SIGNAL語句

使用SIGNAL語句在存儲的程式(例如存儲過程,存儲函數觸發器事件)中向調用者返回錯誤或警告條件。 SIGNAL語句提供了對返回值(如值和消息SQLSTATE)的資訊的控制。

以下說明SIGNAL語句的語法:

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子句。如果要使用值返回多個條件資訊項名稱,則需要用逗號分隔每個名稱/值對。

condition_information_item_name可以是MESSAGE_TEXTMYSQL_ERRORNOCURSOR_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>

MySQL RESIGNAL語句

除了SIGNAL語句,MySQL還提供了用於引發警告或錯誤條件的RESIGNAL語句。

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 ;

下麵我們來調用Divide()存儲過程。

CALL Divide(10,0,@result);

執行上面語句,得到以下結果 -

mysql> CALL Divide(10,0,@result);
1644 - Division by zero / Denominator cannot be zero

在本教學中,我們向您展示了如何使用SIGNALRESIGNAL語句引發存儲程式中的錯誤條件。


上一篇: MySQL存儲過程 下一篇: MySQL視圖