在Java中可以通過Exception、throw等實現異常處理,在Mysql存儲過程中同樣存在類似的一套機制,不過在Mysql中是通過CONDITION來定義異常情況,通過HANDLER來處理CONDITION,以下爲詳細的語法。
在存儲程序執行期間可能出現需要特殊處理的情況,例如退出當前程序塊或繼續執行。可以爲一般情況(如警告或異常)或特定情況(如特定的錯誤代碼)定義處理程序。特定條件可以在處理程序中指定名稱並以這種方式引用。
一、DECLARE ... CONDITION 語句
DECLARE condition_name CONDITION FOR condition_value
condition_value: {
mysql_error_code
| SQLSTATE [VALUE] sqlstate_value
}
DECLARE ... CONDITION語句聲明命名錯誤條件,將名稱與需要特定處理的條件相關聯。 可以在後續的DECLARE ... HANDLER語句中引用該名稱。
條件聲明必須出現在遊標或處理程序聲明之前。
DECLARE ... CONDITION的condition_value表示要與條件名稱關聯的特定條件或條件類別。 它可以採用以下形式:
- mysql_error_code:整數文字,指示MySQL錯誤代碼。
注意:不要使用MySQL錯誤代碼0,因爲這表示成功而不是錯誤情況。
- SQLSTATE [VALUE] sqlstate_value:5個字符的字符串文字,指示SQLSTATE值。
注意:不要使用以“ 00”開頭的SQLSTATE值,因爲這些值表示成功而不是錯誤情況。
SIGNAL或使用RESIGNAL語句中引用的CONDITION名稱必須與SQLSTATE值關聯,而不是與MySQL錯誤代碼關聯。
通過爲條件聲明名稱,可以更容易地看出處理程序的目的:
DECLARE no_such_table CONDITION FOR 1051;
DECLARE CONTINUE HANDLER FOR no_such_table
BEGIN
-- body of handler
END;
這是相同條件的命名條件,但是基於相應的SQLSTATE值而不是MySQL錯誤代碼:
DECLARE no_such_table CONDITION FOR SQLSTATE '42S02';
DECLARE CONTINUE HANDLER FOR no_such_table
BEGIN
-- body of handler
END;
二、DECLARE ... HANDLER 語句
DECLARE handler_action HANDLER
FOR condition_value [, condition_value] ...
statement
handler_action: {
CONTINUE
| EXIT
| UNDO
}
condition_value: {
mysql_error_code
| SQLSTATE [VALUE] sqlstate_value
| condition_name
| SQLWARNING
| NOT FOUND
| SQLEXCEPTION
}
DECLARE ... HANDLER語句指定處理一個或多個條件的處理程序。 如果出現這些情況之一,則執行指定的語句。 語句可以是簡單的語句,例如SET var_name = value,也可以是使用BEGIN和END編寫的複合語句。
handler_action值指示在執行處理程序語句後處理程序將執行的操作:
CONTINUE:繼續執行當前程序。
EXIT:執行終止於聲明處理程序的BEGIN ... END複合語句。 即使條件發生在內部塊中,也是如此。
UNDO:不支持。(Mysql 5.6)
DECLARE ... HANDLER的condition_value指示激活處理程序的特定條件或條件類別。 它可以採用以下形式:
mysql_error_code:整數文字,指示MySQL錯誤代碼,例如1051,用於指定“未知表”:
DECLARE CONTINUE HANDLER FOR 1051
BEGIN
-- body of handler
END;
SQLSTATE [VALUE] sqlstate_value:5個字符的字符串文字,指示SQLSTATE值,例如“ 42S01”,用於指定“未知表”:
DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02'
BEGIN
-- body of handler
END;
//TODO
三、GET DIAGNOSTICS 語句
SQL語句產生的診斷信息將填充診斷區域。 GET DIAGNOSTICS語句使應用程序可以檢查此信息。
執行GET DIAGNOSTICS不需要特殊特權。
GET DIAGNOSTICS通常在存儲程序的處理程序中使用,但是它是MySQL的擴展,允許在處理程序上下文之外檢查任何SQL語句的執行。
要獲取條件信息,請指定條件編號並將所需的條件項檢索到目標變量中。 GET DIAGNOSTICS的此實例將SQLSTATE值和錯誤消息分配給用戶變量@ p3和@ p4:
GET DIAGNOSTICS CONDITION 1
@p3 = RETURNED_SQLSTATE, @p4 = MESSAGE_TEXT;
//TODO
四、RESIGNAL 語句
RESIGNAL傳遞錯誤條件信息,該信息在存儲過程或函數,觸發器或事件內的複合語句內的條件處理程序執行期間可用。 RESIGNAL可能會在傳遞某些或所有信息之前對其進行更改。 RESIGNAL與SIGNAL有關,但是RESIGNAL可能會在修改它之後而不是像SIGNAL那樣發起條件,而是中繼現有條件信息。
RESIGNAL使處理錯誤和返回錯誤信息成爲可能。否則,通過在處理程序中執行SQL語句,會破壞導致處理程序激活的信息。如果給定的處理程序可以處理部分情況,則RESIGNAL還可以使某些過程更短,然後將條件“向上”傳遞給另一個處理程序。
執行RESIGNAL語句不需要特權。
所有形式的RESIGNAL都要求當前上下文是條件處理程序。否則,RESIGNAL是非法的,並且在處理程序不活動時發生RESIGNAL錯誤。
- RESIGNAL Alone
一個簡單的RESIGNAL意味着“傳遞錯誤而不做任何更改”。它恢復最後一個診斷區域並使其成爲當前診斷區域。也就是說,它“彈出”診斷區域堆棧。
RESIGNAL;
- RESIGNAL使用新的信號信息
//TODO
- RESIGNAL使用條件值和可選的新信號信息
//TODO
五、SIGNAL 語句
//TODO
六、處理程序的規則範圍
//TODO
七、MySQL診斷(Diagnostics)區域
//TODO
八、CONDITION處理和OUT或INOUT參數
如果存儲過程因未處理的異常退出,則OUT和INOUT參數的修改後的值不會傳播回調用方。
如果異常由包含RESIGNAL語句的CONTINUE或EXIT處理程序處理,則RESIGNAL的執行會彈出Diagnostics Area堆棧,從而發出異常信號(即,進入處理程序之前存在的信息)。 如果異常是錯誤,則不會將OUT和INOUT參數的值傳播回調用方。
九、CONDITION處理的限制
禁止將SIGNAL, RESIGNAL, GET DIAGNOSTICS作爲準備好的語句。 例如,此語句無效:
PREPARE stmt1 FROM 'SIGNAL SQLSTATE "02000"';
標準SQL具有診斷區域堆棧,其中包含每個嵌套執行上下文的診斷區域。 標準SQL語法包括GET STACKED DIAGNOSTICS,用於引用堆積區域。 MySQL不支持STACKED關鍵字,因爲只有一個診斷區域包含來自最近寫入該語句的語句的信息。