控制結構就是任何程式的基礎,不管是 SQL script、Python code,還是火星上的機器人要不要發訊號回家或去火山口旁邊找生命,都靠它們。
在 PL/pgSQL 裡,控制結構幫我們:
- 如果條件成立,就執行特定動作。
- 控制 code 的執行順序。
- 實現決策邏輯。
你可以把它們想像成馬路上的交通標誌:「看到 STOP 就停,看到綠燈就走!」
PL/pgSQL 裡最常見的控制結構有:
IF– 檢查條件,然後執行對應的指令。CASE– 當條件很多時,IF的替代方案。RETURN– 結束 function 執行並回傳結果。
你應該已經有點概念了。其實學過其他程式語言後,這些東西真的超簡單。
條件運算子 IF
IF 運算子用來在某個條件 TRUE(成立)時才執行 code。基本結構如下:
IF 條件 THEN
-- 如果條件成立要執行的 code。
ELSE
-- 如果條件不成立要執行的替代 code。
END IF;
來寫個 function,接收一個數字,回傳它是偶數還是奇數:
CREATE OR REPLACE FUNCTION check_even_odd(num INTEGER)
RETURNS TEXT AS $$
BEGIN
IF num % 2 = 0 THEN
RETURN '數字是偶數';
ELSE
RETURN '數字是奇數';
END IF;
END;
$$ LANGUAGE plpgsql;
現在來測試一下:
SELECT check_even_odd(4); -- 數字是偶數
SELECT check_even_odd(7); -- 數字是奇數
簡單說明一下:IF num % 2 = 0 THEN 就是在檢查這個數字能不能被 2 整除。
ELSIF 條件
有時候一個條件不夠,你想要檢查多個條件,這時就要用 ELSIF。
假設我們有個 function,根據溫度回傳文字訊息:
CREATE OR REPLACE FUNCTION temperature_comment(temp INTEGER)
RETURNS TEXT AS $$
BEGIN
IF temp < 0 THEN
RETURN '超級冷!';
ELSIF temp >= 0 AND temp <= 20 THEN
RETURN '有點涼';
ELSE
RETURN '很溫暖!';
END IF;
END;
$$ LANGUAGE plpgsql;
測試一下:
SELECT temperature_comment(-5); -- 超級冷!
SELECT temperature_comment(15); -- 有點涼
SELECT temperature_comment(25); -- 很溫暖!
CASE 語法
如果你有一堆條件,CASE 就是你的救星。它有點像 IF,但寫起來更「優雅」。
CASE
WHEN 條件_1 THEN 值_1
WHEN 條件_2 THEN 值_2
ELSE 預設值
END;
來寫個 function,根據分數回傳文字評價:
CREATE OR REPLACE FUNCTION grade_comment(score INTEGER)
RETURNS TEXT AS $$
BEGIN
RETURN CASE
WHEN score >= 90 THEN '超棒'
WHEN score >= 75 THEN '不錯'
WHEN score >= 50 THEN '及格'
ELSE '不及格'
END;
END;
$$ LANGUAGE plpgsql;
測試一下:
SELECT grade_comment(95); -- 超棒
SELECT grade_comment(80); -- 不錯
SELECT grade_comment(45); -- 不及格
小提醒:跟 IF 不一樣,CASE 會直接回傳值,所以 RETURN 可以直接寫在 CASE 裡面。
RETURN 運算子
RETURN 會結束 function 執行並回傳一個值。這對 PL/pgSQL 的 function 超重要,因為你宣告了 RETURNS,就一定要回傳東西(像是文字、數字等等)。
來看個最簡單的 RETURN 範例:
CREATE OR REPLACE FUNCTION return_example()
RETURNS TEXT AS $$
BEGIN
RETURN 'Hello, World!';
END;
$$ LANGUAGE plpgsql;
結果:
SELECT return_example(); -- Hello, World!
但如果 function 裡有多個分支呢?像是檢查輸入資料。這時 RETURN 會出現在 function 的不同地方:
CREATE OR REPLACE FUNCTION check_positive_negative(num INTEGER)
RETURNS TEXT AS $$
BEGIN
IF num > 0 THEN
RETURN '正數';
ELSIF num = 0 THEN
RETURN '零';
ELSE
RETURN '負數';
END IF;
END;
$$ LANGUAGE plpgsql;
測試一下:
SELECT check_positive_negative(10); -- 正數
SELECT check_positive_negative(0); -- 零
SELECT check_positive_negative(-5); -- 負數
常見錯誤跟容易搞混的地方
- 漏掉
END運算子: 忘記寫END CASE;或END IF;,PostgreSQL 會馬上提醒你要結束 code block。 - 用
ELSIF時的邏輯錯誤: 條件順序很重要!比較廣泛的條件(temp > 0)不能寫在比較特定的條件(temp > 20)前面。 - 忘記
RETURN: 在 PL/pgSQL 裡,只要 function 宣告了RETURNS,就一定要回傳東西。
就這樣啦!我們已經把 PL/pgSQL 裡控制結構和邏輯的基礎都講完了。這些東西你之後寫更複雜的 function 一定用得到!下次我們會講迴圈跟它們的用法。
GO TO FULL VERSION