MySQL 預存程序提供三種標準循環:WHILE、REPEAT、LOOP。其中 LOOP 為無條件循環,需配合 LEAVE(跳出)與 ITERATE(繼續下一輪)控制流程,適合複雜跳轉邏輯。本文深度解析 LOOP 語法、標籤機制、巢狀循環控制與實戰範例。
[begin_label:] LOOP
statement_list
END LOOP [end_label]
LEAVE/ITERATE 引用,巢狀循環時必須指定以區分層級。LEAVE 跳出**,否則無限循環。| 語句 | 作用 | 相當於 |
|---|---|---|
LEAVE label | 立即跳出指定標籤的循環 | break |
ITERATE label | 跳過本次剩餘語句,直接進入下一輪迭代 | continue |
DELIMITER $$
CREATE PROCEDURE myProc()
BEGIN
DECLARE i INT DEFAULT 0;
loop1: LOOP
SET i = i + 1;
IF i >= 10 THEN
LEAVE loop1; -- 達到 10 跳出循環
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 is an odd number
-- 3 is an odd number
-- 5 is an odd number
-- 7 is an odd number
-- 9 is an odd number
i>=10 偽 → MOD(1,2)=0 偽 → 輸出 1MOD(2,2)=0 真 → ITERATE 跳過輸出 → 下一輪i>=10 真 → LEAVE 結束DELIMITER $$
CREATE PROCEDURE nested_loop()
BEGIN
DECLARE x, y INT DEFAULT 0;
outer_loop: LOOP
SET x = x + 1;
IF x > 3 THEN LEAVE outer_loop; END IF;
inner_loop: LOOP
SET y = y + 1;
IF y >= 5 THEN
SET y = 0; -- 重置內層計數器
ITERATE outer_loop; -- 跳回外層下一輪
END IF;
SELECT CONCAT('x=', x, ', y=', y);
END LOOP inner_loop;
END LOOP outer_loop;
END$$
DELIMITER ;
CALL nested_loop();
-- 輸出 x=1,y=1~4 → x=2,y=1~4 → x=3,y=1~4
關鍵: ITERATE outer_loop 直接跳到外層循環的下一輪,內層循環自動結束重置。
| 循環類型 | 測試時機 | 適用場景 | 典型用法 |
|---|---|---|---|
| WHILE | 前測試 | 已知次數、條件明確 | 計數器、游標遍歷 |
| REPEAT | 後測試 | 至少執行一次 | 菜單選單、輸入驗證 |
| LOOP | 無內建 | 複雜跳轉、多出口 | 狀態機、巢狀控制、需 ITERATE/LEAVE 精準控制 |
main_loop),便於維護與除錯。LEAVE 條件。DECLARE 在 BEGIN 後,循環內修改的變數對外層可見。DROP PROCEDURE IF EXISTS myProc; 避免殘留。LOOP 是 MySQL 預存程序中最靈活的循環結構,透過 LEAVE/ITERATE + 標籤機制可實現任意複雜控制流。掌握標籤精準控制巢狀循環、養成防無限循環習慣、選擇適合場景的循環類型,是編寫健壯預存程序的關鍵。