Oracle數據庫之PL/SQL流程控制語句
在任何計算機編程語言(如C,Java,C#等)都有各種流程控制語句,同樣,在PL/SQL中也存在這樣的流程控制結構。
幾種常見的流程控制結構:

一、條件結構
1. 簡單IF結構
-- 簡單IF結構 IF <布爾表達式> THEN 滿足條件時執行的語句 END IF;
2. IF-ELSE結構
-- IF-ELSE結構 IF <布爾表達式> THEN 滿足條件時執行的語句 ELSE 不滿足條件時執行的語句 END IF;
3. 多重IF
-- 多重IF IF <布爾表達式1> THEN 滿足條件1時執行的語句 ELSIF <布爾表達式2> THEN 滿足條件2時執行的語句 ELSIF <布爾表達式3> THEN 滿足條件3時執行的語句 ELSE 滿足條件1、2、3均不滿足時執行的語句 END IF;
注意:ELSIF不能寫成ELSEIF
示例:
DECLARE emp_id employee.id%TYPE := &empid; emp_salary employee.salary%TYPE; info VARCHAR2(50); BEGIN SELECT salary INTO emp_salary FROM employee WHERE id = emp_id; /* 根據薪資情況判斷 */ IF emp_salary < 1500 THEN info := '太少了,不加就辭職!'; ELSIF emp_salary <3000 THEN info := '還將就,先干着吧!'; ELSE info := '目前還比較滿意,以后再看!'; END IF; DBMS_OUTPUT.PUT_LINE(info); EXCEPTION WHEN no_data_found THEN DBMS_OUTPUT.PUT_LINE('沒有數據~!'); WHEN others THEN DBMS_OUTPUT.PUT_LINE(sqlcode || '---' || sqlerrm); END;
4. CASE
語法一:
CASE 條件表達式 WHEN 條件表達式結果1 THEN 語句1 WHEN 條件表達式結果2 THEN 語句2 ...... WHEN 條件表達式結果n THEN 語句n [ELSE 條件表達式結果] END CASE;
示例:
DECLARE grade CHAR(1); BEGIN grade := '&g'; CASE grade WHEN 'A' THEN DBMS_OUTPUT.PUT_LINE('Excellent'); WHEN 'B' THEN DBMS_OUTPUT.PUT_LINE('Very Good'); WHEN 'C' THEN DBMS_OUTPUT.PUT_LINE('Good'); WHEN 'D' THEN DBMS_OUTPUT.PUT_LINE('Fair'); WHEN 'F' THEN DBMS_OUTPUT.PUT_LINE('Poor'); ELSE DBMS_OUTPUT.PUT_LINE('No such grade'); END CASE; END;
語法二:
CASE WHEN 條件表達式1 THEN 語句1 WHEN 條件表達式2 THEN 語句2 ...... WHEN 條件表達式n THEN 語句n [ELSE 語句] END CASE;
示例:
DECLARE grade CHAR(1); BEGIN grade := '&g'; CASE WHEN grade = 'A' THEN DBMS_OUTPUT.PUT_LINE('Excellent'); WHEN grade = 'B' THEN DBMS_OUTPUT.PUT_LINE('Very Good'); WHEN grade = 'C' THEN DBMS_OUTPUT.PUT_LINE('Good'); WHEN grade = 'D' THEN DBMS_OUTPUT.PUT_LINE('Fair'); WHEN grade = 'F' THEN DBMS_OUTPUT.PUT_LINE('Poor'); ELSE DBMS_OUTPUT.PUT_LINE('No such grade'); END CASE; END;
二、循環結構
1. 簡單循環
語法:
LOOP 循環體語句; [EXIT WHEN <條件語句>] END LOOP;
示例1:
DECLARE x NUMBER(2) := 0; BEGIN LOOP x := x + 1; DBMS_OUTPUT.PUT_LINE('x的當前值為:'||x); EXIT WHEN x = 10; END LOOP; END;
示例2:
DECLARE x NUMBER := 0; BEGIN LOOP DBMS_OUTPUT.PUT_LINE ('循環中: x = ' || TO_CHAR(x)); x := x + 1; IF x > 3 THEN EXIT; END IF; END LOOP; DBMS_OUTPUT.PUT_LINE(' 循環結束: x = ' || TO_CHAR(x)); END;
2. WHILE循環
語法:
WHILE <布爾表達式> LOOP 循環體語句; END LOOP;
示例1:
DECLARE done BOOLEAN := FALSE; BEGIN WHILE done LOOP DBMS_OUTPUT.PUT_LINE ('Oh, no! It's wrong!'); done := TRUE; END LOOP; WHILE NOT done LOOP DBMS_OUTPUT.PUT_LINE ('Hello, world!'); done := TRUE; END LOOP; END;
3. FOR循環
語法:
[<<標簽>>] FOR 循環計數器 IN [ REVERSE ] 下限 .. 上限 LOOP 循環體語句; END LOOP [<<標簽>>];
說明:
使用關鍵字REVERSE,循環變量自動減1。跟在IN REVERSE后面的數字應是從小到大的順序,而且必須是整數,不能是變量或表達式。
示例1:
BEGIN DBMS_OUTPUT.PUT_LINE ('下限 < 上限:'); FOR i IN 1..3 LOOP DBMS_OUTPUT.PUT_LINE (i); END LOOP; DBMS_OUTPUT.PUT_LINE ('下限 = 上限:'); FOR i IN 2..2 LOOP DBMS_OUTPUT.PUT_LINE (i); END LOOP; DBMS_OUTPUT.PUT_LINE ('下限 > 上限:'); FOR i IN 3..1 LOOP DBMS_OUTPUT.PUT_LINE (i); END LOOP; END;
輸出結果:
下限 < 上限: 1 2 3 下限 = 上限: 2 下限 > 上限:
示例2:
BEGIN DBMS_OUTPUT.PUT_LINE ('反轉 -- 下限 < 上限:'); FOR i IN REVERSE 1..3 LOOP DBMS_OUTPUT.PUT_LINE (i); END LOOP; DBMS_OUTPUT.PUT_LINE ('反轉 -- 下限 = 上限:'); FOR i IN REVERSE 2..2 LOOP DBMS_OUTPUT.PUT_LINE (i); END LOOP; DBMS_OUTPUT.PUT_LINE ('反轉 -- 下限 > 上限:'); FOR i IN REVERSE 3..1 LOOP DBMS_OUTPUT.PUT_LINE (i); END LOOP; END;
運行結果:
反轉 -- 下限 < 上限: 3 2 1 反轉 -- 下限 = 上限: 2 反轉 -- 下限 > 上限:
循環結構中,均可以在適當的時候構建條件使用EXIT退出循環結構。
三、順序結構
1. GOTO
GOTO語句用於跳轉到指定<<標號>>去執行語句,是無條件跳轉到指定的標號去的意思。
注意:標號是用<< >>括起來的標識符。
語法:
GOTO label;
GOTO語句缺點是會增加程序的復雜性,降低可讀性,所以Oracle建議不要使用。
示例:
DECLARE p VARCHAR2(30); n PLS_INTEGER := 37; BEGIN FOR j in 2..ROUND(SQRT(n)) LOOP IF n MOD j = 0 THEN p := ' 不是素數'; GOTO print_now; END IF; END LOOP; p := ' 是素數'; <<print_now>> DBMS_OUTPUT.PUT_LINE(TO_CHAR(n) || p); END;
2. NULL
空語句,執行沒有任何實際效果,可以使某些語句變得有意義,提高程序的可讀性,保證其他語句結構的完整性和正確性,通常用於占位置。
示例1:
DECLARE valid BOOLEAN := TRUE; BEGIN GOTO update_row; IF valid THEN <<update_row>> NULL; END IF; END;
示例2:
DECLARE v_job_id VARCHAR2(10); v_emp_id NUMBER(6) := 110; BEGIN SELECT job_id INTO v_job_id FROM employees WHERE employee_id = v_emp_id; IF v_job_id = 'SA_REP' THEN UPDATE employees SET commission_pct = commission_pct * 1.2; ELSE NULL; END IF; END;
