在本教學中,您將學習如何使用SIGNAL
和RESIGNAL
語句來引發儲存過程中的錯誤條件。
使用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_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>
除了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
在本教學中,我們向您展示了如何使用SIGNAL
和RESIGNAL
語句引發儲存程式中的錯誤條件。