有時候,不希望存儲過程拋出錯誤中止執行,而是希望返回一個錯誤碼。 Mysql 支持異常處理,通過定義 CONTINUE/EXIT 異常處理的 HANDLER 來捕獲 SQLWARNING/NOT FOUND/SQLEXCEPTION (警告 / 無數據 / 其他異常)。其中, FOR 後面可以改為 SQLWARNING, NOT FOUND, SQLEXCEPTION 來指示所有異常都處理,相當於 oracle 中的 others 。例如,當不進行異常處理時,以下代碼將直接拋出一個 ERROR 1062 (23000) 錯誤:
CREATE PROCEDURE test_proc_ins1(
IN i_id INT,
IN i_name VARCHAR(100)
)
BEGIN
INSERT INTO testproc VALUES (i_id,i_name);
INSERT INTO testproc VALUES (i_id,i_name);
END;
經過異常處理後,可以避免拋出錯誤,而是定義一個返回參數 o_ret 賦予特殊值來表示失敗,這樣,比如在 java 代碼中,可以通過獲取返回值而不是捕獲異常的方式來處理業務邏輯。例如將返回值設置為 -1:
CREATE PROCEDURE test_proc_ins1(
IN i_id INT,
IN i_name VARCHAR(100),
OUT o_ret INT)
BEGIN
DECLARE EXIT HANDLER FOR SQLSTATE '23000' set o_ret = -1;
-- 也可以這樣使用:
-- DECLARE EXIT HANDLER FOR SQLWARNING,NOT FOUND,SQLEXCEPTION set o_ret=-1;
INSERT INTO testproc VALUES (i_id,i_name);
INSERT INTO testproc VALUES (i_id,i_name);
set o_ret = 1;
END;
當然,對於特定的SQL語句,也可以指定比如主鍵沖突,就rollback;
DECLARE exit HANDLER FOR SQLSTATE '23000'
delimiter //
CREATE PROCEDURE TEST()
BEGIN
DECLARE exit HANDLER FOR SQLEXCEPTION,SQLWARNING,NOT FOUND
begin
rollback;
insert into bb values('error');
end;
START TRANSACTION;
INSERT INTO aa VALUES (1);
INSERT INTO aa VALUES (2);
COMMIT;
END;
//
CALL test()//