MySQL signal和esignal語句

2019-10-16 22:56:34

在本教學中,您將學習如何使用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語句引發儲存程式中的錯誤條件。