MySQL 5.0+ 引入預存程序,才支援在 SQL 內使用流程控制(IF、WHILE、LOOP、REPEAT、ITERATE、LEAVE)。本文詳細解析三種標準循環結構、條件判斷、參數傳遞與實戰範例,助你掌握伺服器端程式邏輯開發。
| 關鍵字 | 用途 | 適用場景 |
|---|---|---|
IF ... THEN ... ELSE ... END IF | 條件分支 | 單一條件多重分支 |
CASE ... WHEN ... THEN ... END CASE | 多條件分支 | 多值比對 |
WHILE condition DO ... END WHILE | 前測試循環 | 已知循環次數或條件 |
REPEAT ... UNTIL condition END REPEAT | 後測試循環 | 至少執行一次 |
LOOP ... END LOOP | 無條件循環 | 配合 LEAVE/ITERATE 控制 |
LEAVE label | 跳出指定標籤循環 | 等同 break |
ITERATE label | 跳過本次迭代進入下一次 | 等同 continue |
DELIMITER //
CREATE PROCEDURE test_while(IN in_count INT)
BEGIN
DECLARE cnt INT DEFAULT 0;
WHILE cnt < in_count DO
SET cnt = cnt + 1;
END WHILE;
SELECT cnt AS result;
END//
DELIMITER ;
CALL test_while(10); -- 輸出 10
特點: 先判斷條件再執行,若初始條件不滿足則零次執行。
DELIMITER //
CREATE PROCEDURE test_repeat(IN in_count INT)
BEGIN
DECLARE cnt INT DEFAULT 0;
REPEAT
SET cnt = cnt + 1;
UNTIL cnt >= in_count
END REPEAT;
SELECT cnt;
END//
DELIMITER ;
特點: 保證至少執行一次,適合「先做後判斷」邏輯。
DELIMITER $$
CREATE PROCEDURE myProc()
BEGIN
DECLARE i INT DEFAULT 0;
loop1: LOOP
SET i = i + 1;
IF i >= 10 THEN
LEAVE loop1; -- 跳出循環
ELSEIF MOD(i, 2) = 0 THEN
ITERATE loop1; -- 跳過偶數,直接下一輪
END IF;
SELECT CONCAT(i, ' is an odd number');
END LOOP loop1;
END$$
DELIMITER ;
CALL myProc(); -- 輸出 1,3,5,7,9
特點: 最靈活,需自行控制終止條件,適合複雜跳轉邏輯。
DELIMITER //
CREATE PROCEDURE increment(IN in_count INT)
BEGIN
DECLARE cnt INT DEFAULT 0;
increment_loop: LOOP
SET cnt = cnt + 1;
IF cnt < 20 THEN
ITERATE increment_loop; -- 計數器 < 20 時跳過後續,直接下一輪
END IF;
IF cnt > in_count THEN
LEAVE increment_loop; -- 超過傳入參數則結束
END IF;
END LOOP increment_loop;
SELECT cnt AS final_count;
END//
DELIMITER ;
CALL increment(3); -- 輸出 20(先跑到 20,再檢查 > 3 才結束)
邏輯解析:
ITERATE 導致直接進入下一輪,不執行後續判斷。cnt < 20 為假,進入第二個 IF,若 cnt > in_count 則 LEAVE。increment(3) 時,20 > 3 滿足,結束並返回 20。DELIMITER //
CREATE FUNCTION myFunction(quantity INT) RETURNS INT
DETERMINISTIC
BEGIN
WHILE quantity MOD 12 > 0 DO
SET quantity = quantity + 1;
END WHILE;
RETURN quantity; -- 函數必須用 RETURN
END//
DELIMITER ;
SELECT myFunction(10); -- 12(補齊到 12 的倍數)
SELECT myFunction(24); -- 24
差異提醒: 函數用 RETURN 回傳單一值;預存程序用 SELECT 輸出結果集或 OUT 參數回傳。
// 或 $$,結束後改回 ;。LEAVE 條件,並在開發環境測試小數據驗證。DECLARE 必須置於 BEGIN 之後、任何其他語句之前。process_loop),避免巢狀循環混淆。MySQL 預存程序提供完整的程序化能力:WHILE 適合已知次數、REPEAT 適合至少一次、LOOP 適合複雜控制流。配合 IF/CASE、LEAVE/ITERATE、標籤機制,可實現各類業務邏輯。實務上建議「能在應用層解決的不下放到資料庫」,僅將高頻、原子性強的資料操作封裝為預存程序。