CREATE TABLE t2 (s1 INT PRIMARY KEY) ENGINE=InnoDB;
CREATE TABLE t3 (s1 INT, KEY(s1), FOREIGN KEY(s1) REFERENCES t2(s1)) ENGINE=InnoDB;
CREATE TABLE error_log (msg CHAR(80));
CREATE PROCEDURE p22 (p1 INT)
BEGIN
DECLARE EXIT HANDLER FOR 1216
INSERT INTO error_log VALUES (CONCAT('Time: ', CURRENT_DATE, '. FK Fail: ', p1));
INSERT INTO t3 VALUES (p1);
END;
呼叫 `CALL p22(5)` 時,5 不在 t2 中,觸發 1216 錯誤,EXIT HANDLER 寫日誌並退出複合語句,t3 無資料寫入。
| 類型 | 行為 |
|---|---|
| EXIT | 處理完離開當前 BEGIN/END 區塊,後續語句不執行 |
| CONTINUE | 處理完回到錯誤語句下一行繼續執行 |
CREATE PROCEDURE p23 ()
BEGIN
DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1;
SET @x = 1; INSERT INTO t4 VALUES (1); -- 成功
SET @x = 2; INSERT INTO t4 VALUES (1); -- 重複主鍵,觸發 HANDLER,@x2=1
SET @x = 3; -- 繼續執行
END;
執行後 `@x=3, @x2=1`,證明流程未中斷。
CREATE PROCEDURE p24 ()
BEGIN
DECLARE `Constraint Violation` CONDITION FOR SQLSTATE '23000';
DECLARE EXIT HANDLER FOR `Constraint Violation` ROLLBACK;
START TRANSACTION;
INSERT INTO t2 VALUES (1);
INSERT INTO t2 VALUES (1); -- 觸發約束錯誤,整筆事務回滾
COMMIT;
END;
NOT FOUND (SQLSTATE 02000) — 游標無資料SQLEXCEPTION — 所有錯誤SQLWARNING — 警告CREATE PROCEDURE p25 (OUT ret INT)
BEGIN
DECLARE a, b INT;
DECLARE cur_1 CURSOR FOR SELECT s1 FROM t;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET b = 1;
OPEN cur_1;
REPEAT
FETCH cur_1 INTO a;
UNTIL b = 1 END REPEAT;
CLOSE cur_1;
SET ret = a; -- 返回最後一行值
END;
關鍵順序:變量 → 條件 → 游標 → HANDLER,否則報錯。
| 權限 | 用途 |
|---|---|
| CREATE ROUTINE | 建立存儲過程/函數/視圖/表 (Root 擁有) |
| EXECUTE | 執行特定過程 (建立者自動擁有) |
| SHOW ROUTINE (規劃中) | 檢視過程定義 |
CREATE PROCEDURE p26 () SQL SECURITY INVOKER SELECT COUNT(*) FROM t;
CREATE PROCEDURE p27 () SQL SECURITY DEFINER SELECT COUNT(*) FROM t;
GRANT INSERT ON db5.* TO peter;
善用 DEFINER 可實現「最小權限原則」:應用帳號僅需 EXECUTE 權限,核心表權限收歸定義者。