循環可以讓你重複執行一段程式碼,只要某個條件成立,或是針對某個資料集做迭代。這超級適合自動化工作、處理大量資料或是做重複的操作。
想像一下,你要手動把糖果發給每個小朋友,肯定會亂成一團!不如你直接走過小朋友的名單,一個一個發糖果。這個「走過名單」就是循環啦。
PostgreSQL 支援幾種循環:
LOOP— 通用型循環,要你自己明確結束它。FOR— 針對數字範圍或查詢結果做固定次數的循環。WHILE— 只要條件成立就一直跑的循環。
我們一個一個來看。
無限循環:LOOP
LOOP 是 PL/pgSQL 裡最基本的循環型態,會一直重複執行區塊。這個循環會無限跑下去,除非你用 EXIT 手動跳出來。
語法:
LOOP
-- 你的程式碼寫這裡
END LOOP;
來個例子,用 LOOP 算 1 到 10 的總和:
DO $$
DECLARE
counter INT := 1;
sum INT := 0;
BEGIN
LOOP
sum := sum + counter; -- 加上目前的計數器值
counter := counter + 1; -- 計數器加一
-- 如果計數器大於 10 就結束循環
IF counter > 10 THEN
EXIT;
END IF;
END LOOP;
RAISE NOTICE '1 到 10 的總和: %', sum;
END $$;
- 變數
counter每次循環都會加一。 - 條件
IF counter > 10 THEN EXIT;讓計數器超過 10 時結束循環。 - 最後會印出總和。
針對範圍或資料集的循環:FOR
第二種循環,FOR,可以用來:
- 跑數字範圍。
- 跑 SQL 查詢結果。
數字範圍的循環
語法:
FOR variable IN [REVERSE] start..end LOOP
-- 你的程式碼寫這裡
END LOOP;
印出 1 到 5:
DO $$
BEGIN
FOR i IN 1..5 LOOP
RAISE NOTICE '目前的值: %', i;
END LOOP;
END $$;
反向範例:
DO $$
BEGIN
FOR i IN REVERSE 5..1 LOOP
RAISE NOTICE '反向順序: %', i;
END LOOP;
END $$;
SQL 查詢結果的循環
這種方式很適合處理資料表的每一列。
語法:
FOR variable IN QUERY (SELECT ...) LOOP
-- 你的程式碼寫這裡
END LOOP;
來個例子,針對 students 資料表的每一列做迭代:
DO $$
DECLARE
student_name TEXT;
BEGIN
FOR student_name IN QUERY (SELECT name FROM students) LOOP
RAISE NOTICE '哈囉, %!', student_name;
END LOOP;
END $$;
條件循環:WHILE
WHILE 只要條件成立就會一直跑。
語法:
WHILE 條件 LOOP
-- 你的程式碼寫這裡
END LOOP;
來算 1 到 10 的總和,用 WHILE:
DO $$
DECLARE
counter INT := 1;
sum INT := 0;
BEGIN
WHILE counter <= 10 LOOP
sum := sum + counter;
counter := counter + 1;
END LOOP;
RAISE NOTICE '1 到 10 的總和: %', sum;
END $$;
生活中的例子
現在我們已經搞懂循環的基本用法,來看看一些實際應用的例子。
例子 1:產生乘法表
DO $$
DECLARE
i INT;
j INT;
BEGIN
FOR i IN 1..5 LOOP
FOR j IN 1..5 LOOP
RAISE NOTICE '% x % = %', i, j, i * j;
END LOOP;
END LOOP;
END $$;
例子 2:針對查詢結果做迭代。 假設我們有個 products 資料表,欄位有 id 跟 price。我們要把所有價格都加 10%。
DO $$
DECLARE
prod RECORD;
BEGIN
FOR prod IN QUERY (SELECT id, price FROM products) LOOP
UPDATE products
SET price = prod.price * 1.1
WHERE id = prod.id;
END LOOP;
END $$;
常見錯誤跟怎麼避免
在 LOOP 或 WHILE 裡跑無限循環。 如果你忘了加結束條件(EXIT 或 WHILE 裡的正確條件),循環就永遠不會停。這就像開車沒煞車一樣可怕。
查詢結果迭代時出錯。 如果查詢回來的資料結構跟你預期的不一樣,FOR IN QUERY 的循環就會出錯。
在循環裡寫沒效率的查詢。 像是每次循環都 UPDATE,這樣會讓執行速度超慢。這種情況下最好直接用一個 SQL 查詢搞定,不要用循環。
GO TO FULL VERSION