PL/SQL提供完整的結構化程式設計能力,核心包含條件控制(IF/CASE)與迴圈控制(LOOP/FOR/WHILE)兩大類。
IF condition THEN
statements;
END IF;
語意: 條件為TRUE執行THEN~END IF區塊,FALSE/NULL則跳過。
IF condition THEN
statements_1;
ELSE
statements_2;
END IF;
TRUE執行THEN~ELSE,FALSE/NULL執行ELSE~END IF。
IF condition1 THEN
stmt1;
ELSIF condition2 THEN
stmt2;
ELSIF condition3 THEN
stmt3;
ELSE
stmt4;
END IF;
stmt5; -- 後續共同執行
依序評估條件,首個TRUE對應區塊執行後跳至END IF,全 FALSE執行ELSE區塊。
IF (a > b) AND (a > c) THEN
g := a;
ELSE
g := b;
IF c > g THEN
g := c;
END IF;
END IF;
尋找三數最大值經典邏輯。實務建議:層級超過3層考慮重構為CASE或獨立函數。
-- 簡單CASE
CASE expr
WHEN val1 THEN result1
WHEN val2 THEN result2
ELSE result3
END;
-- 搜尋CASE(條件任意複雜)
CASE
WHEN cond1 THEN result1
WHEN cond2 THEN result2
ELSE result3
END;
優點:可嵌入SQL語句、可作為運算式一部分、可讀性優於多層ELSIF。
LOOP
statements;
EXIT [WHEN condition]; -- 必須有退出機制
END LOOP;
WHILE condition LOOP
statements;
END LOOP;
條件為TRUE進入,進入前先判斷,可能零次執行。
-- 正向
FOR i IN 1..10 LOOP
DBMS_OUTPUT.PUT_LINE(i);
END LOOP;
-- 反向
FOR i IN REVERSE 1..10 LOOP
...
END LOOP;
計數器隱式宣告、不可修改、範圍確定時首選。
FOR rec IN (SELECT * FROM emp WHERE deptno = 10) LOOP
DBMS_OUTPUT.PUT_LINE(rec.ename);
END LOOP;
自動OPEN/FETCH/CLOSE,最簡潔的游標遍歷方式。
| 語句 | 作用 | 適用範圍 |
|---|---|---|
| EXIT | 立即退出當前迴圈 | LOOP/WHILE/FOR |
| EXIT WHEN | 條件成立時退出 | LOOP/WHILE/FOR |
| CONTINUE | 跳過本次迭代進入下一次 (11g+) | LOOP/WHILE/FOR |
| GOTO | 無條件跳轉標籤 (慎用) | 區塊內 |
| NULL | 空操作,佔位用 | 任何可執行語句處 |
DECLARE
v_emp_rec emp%ROWTYPE;
v_grade VARCHAR2(1);
v_cnt NUMBER := 0;
v_total NUMBER := 0;
BEGIN
FOR v_emp_rec IN (SELECT * FROM emp) LOOP
v_total := v_total + v_emp_rec.sal;
v_cnt := v_cnt + 1;
-- CASE表達式判斷等級
v_grade := CASE
WHEN v_emp_rec.sal >= 5000 THEN 'A'
WHEN v_emp_rec.sal >= 3000 THEN 'B'
WHEN v_emp_rec.sal >= 1500 THEN 'C'
ELSE 'D'
END;
DBMS_OUTPUT.PUT_LINE(v_emp_rec.ename || ': ' || v_emp_rec.sal || ' -> Grade ' || v_grade);
END LOOP;
DBMS_OUTPUT.PUT_LINE('Avg Salary: ' || ROUND(v_total/v_cnt, 2));
EXCEPTION
WHEN ZERO_DIVIDE THEN
DBMS_OUTPUT.PUT_LINE('No employees found');
END;
BULK COLLECT/FORALLDBMS_PARALLEL_EXECUTE)PL/SQL流程控制提供工業級程式設計能力。核心原則:用CASE替代多層IF、用FOR LOOP替代手工計數、用游標FOR LOOP簡化游標操作、嚴格控制迴圈退出條件、善用CONTINUE簡化邏輯。配合現代特性(11g+ CONTINUE、CASE增強),可編寫清晰、高效、可維護的業務邏輯。