在 DECLARE HANDLER 中執行多條語句,需用 BEGIN ... END 包裹:
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' BEGIN
SET @done = 1;
SET @done2 = 222;
INSERT INTO t VALUES (1); -- 可執行任意語句
END;
DROP TABLE IF EXISTS t;
CREATE TABLE t(id INT);
DROP PROCEDURE IF EXISTS test;
DELIMITER |
CREATE PROCEDURE test()
BEGIN
DECLARE vId INT;
-- 游標查詢空結果集
DECLARE cTest CURSOR FOR SELECT * FROM t;
-- 異常處理:NOT FOUND (02000) 時執行多句
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' BEGIN
SET @done = 1;
SET @done2 = 222;
INSERT INTO t VALUES (1);
END;
OPEN cTest;
FETCH NEXT FROM cTest INTO vId; -- 觸發 NOT FOUND
SET @done2 = 333;
CLOSE cTest;
END;
|
DELIMITER ;
CALL test();
SELECT @done2 FROM dual; -- 333 (主程序繼續執行到此行)
SELECT * FROM t; -- 1 (HANDLER 中的 INSERT 生效)
CONTINUE HANDLER:執行區塊後回到主程序繼續(@done2 從 222 變 333)EXIT HANDLER:執行區塊後離開程序,@done2 將保持 222FETCH 空結果集 → 觸發 SQLSTATE '02000' (NOT FOUND)| HANDLER 類型 | 執行區塊後 | @done2 最終值 | 適用場景 |
|---|---|---|---|
CONTINUE ... BEGIN ... END | 回主程序下一行 | 333 | 記錄日誌、計數、清理後繼續 |
EXIT ... BEGIN ... END | 離開當前 BEGIN...END | 222 | 嚴重錯誤、需中止、回滾交易 |
CREATE PROCEDURE process_data()
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE v_id INT;
DECLARE cur CURSOR FOR SELECT id FROM source_table;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN cur;
read_loop: LOOP
FETCH cur INTO v_id;
IF done THEN LEAVE read_loop; END IF;
-- 處理邏輯可能拋出例外
BEGIN
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN
INSERT INTO error_log (err_id, err_msg) VALUES (v_id, 'Processing failed');
-- 記錄後繼續處理下一筆
END;
CALL risky_operation(v_id);
END;
END LOOP;
CLOSE cur;
END;
DECLARE var ...)DECLARE condition ...)DECLARE cursor ...)DECLARE HANDLER ...)ERROR 1337 (HY000): Variable or condition declaration after cursor or handler declaration」