有時候迴圈跑得很順——直到你有理由想要提早停下來。幸好,PL/pgSQL 給我們很方便的工具來搞定這件事。
用 EXIT 中斷迴圈
有時候你會想要讓迴圈在還沒跑完之前就結束。可能是因為找到你要的值、發現錯誤,或是根據某個條件決定不再繼續。這時就可以用 EXIT。
EXIT 就像是在跟迴圈說:「夠了,你的任務完成了,可以停下來了」。
EXIT 的語法超簡單:
EXIT WHEN 條件;
這裡的 WHEN 關鍵字就是指定什麼時候要結束這個迴圈。如果沒寫條件,EXIT 會直接馬上結束目前的迴圈。
範例:找到指定值就結束迴圈
假設我們有一個學生編號的欄位,要找出特定 id 的學生。一旦找到,就要結束迴圈。
DO $$
DECLARE
student_id INT;
BEGIN
FOR student_id IN 1..100 LOOP
RAISE NOTICE '正在檢查學生 ID: %', student_id;
-- 如果找到目標學生,就結束迴圈
IF student_id = 42 THEN
RAISE NOTICE '找到 ID 為 42 的學生!';
EXIT;
END IF;
END LOOP;
END $$;
這個例子裡,迴圈會從 1 跑到 100,檢查每個「學生」。只要找到 ID 42,就會印出訊息並結束。
用 CONTINUE 跳過某次迭代
有時候你會想在迴圈裡跳過某些迭代,但還是繼續跑下一個。這很適合你想忽略「不需要」的資料,或是針對某些條件跳過步驟。
CONTINUE 就是在說:「這個條件不 OK,直接跳到下一輪吧」。
CONTINUE 跟 EXIT 很像,只是它不是結束整個迴圈,而是跳過這一輪:
CONTINUE WHEN 條件;
如果條件成立,這一輪就會被跳過,直接進到下一輪。
範例:跳過偶數
這個例子會從 1 跑到 10,但只印出奇數,偶數都跳過。
DO $$
DECLARE
num INT;
BEGIN
FOR num IN 1..10 LOOP
-- 跳過偶數
IF num % 2 = 0 THEN
CONTINUE;
END IF;
RAISE NOTICE '奇數: %', num;
END LOOP;
END $$;
這裡 CONTINUE 會跳過所有 num % 2 = 0(也就是偶數)的迭代。結果只會印出奇數。
EXIT 跟 CONTINUE 一起用
EXIT 跟 CONTINUE 可以一起用,讓你更靈活地控制迴圈。比如你可以用 CONTINUE 跳過不需要的迭代,但如果遇到重要的東西就直接 EXIT。
下面這個例子會跳過所有能被 3 整除的數字,但只要遇到 15 就結束整個迴圈。
DO $$
DECLARE
num INT;
BEGIN
FOR num IN 1..20 LOOP
-- 跳過能被 3 整除的數字
IF num % 3 = 0 THEN
CONTINUE;
END IF;
-- 如果數字是 15 就結束
IF num = 15 THEN
RAISE NOTICE '停在數字 %', num;
EXIT;
END IF;
RAISE NOTICE '目前數字: %', num;
END LOOP;
END $$;
這個迴圈的邏輯是:
- 能被 3 整除的數字會被跳過(
CONTINUE)。 - 如果數字是 15,整個迴圈就結束(
EXIT)。 - 其他數字都會被印出來。
進階範例:跳過不正確資料,遇到嚴重錯誤就結束
現在來個更貼近實務的例子。我們要處理一個學生清單,檢查他們的資料。不正確的紀錄會被跳過,如果遇到「嚴重錯誤」就整個停止處理。
DO $$
DECLARE
student RECORD;
BEGIN
FOR student IN
SELECT * FROM students
LOOP
-- 跳過資料不正確的紀錄
IF student.name IS NULL THEN
RAISE NOTICE '跳過 ID 為 % 的學生:缺少名字', student.id;
CONTINUE;
END IF;
-- 遇到嚴重錯誤就結束
IF student.status = 'ERROR' THEN
RAISE EXCEPTION 'ID 為 % 的學生發生嚴重錯誤', student.id;
EXIT; -- 這行其實多餘,因為 RAISE EXCEPTION 會直接結束執行。
END IF;
-- 處理紀錄
RAISE NOTICE '處理學生: %', student.name;
END LOOP;
END $$;
這個例子裡 CONTINUE 會跳過沒有名字的學生,EXIT(加上 RAISE EXCEPTION)則是在遇到嚴重錯誤時結束整個迴圈。
實用建議與常見錯誤
記得檢查條件邏輯。 在 EXIT WHEN 或 CONTINUE WHEN 裡條件寫錯,可能會讓你的迴圈提早結束或錯過重要資料。
不要過度用 CONTINUE。 如果你的程式碼到處都是 CONTINUE,也許該重新想一下迴圈的邏輯,讓它更簡單。
不要搞混 EXIT 跟 RETURN。 EXIT 只會結束目前的迴圈,但 RETURN 是直接結束整個 function。
小心無窮迴圈。 如果你用 LOOP 但沒有明確的結束條件,又忘了寫 EXIT,你的迴圈可能會永遠跑下去喔。
GO TO FULL VERSION