PL/SQL程序可通過條件或循環結構來控制命令執行的流程。PL/SQL提供了豐富的流程控制語句,與C#一樣也有三種控制結構:
順序結構 條件結構 循環結構
※條件控制
C#中的條件控制使用關鍵字if和switch。PL/SQL中關於條件控制的關鍵字有IF-THEN、IF-THEN-ELSE、IF-THEN-ELSIF和多分枝條件CASE。
★IF-THEN
該結構先判斷一個條件是否為TRUE,條件成立則執行對應的語句塊,與C#中的if語句很相似,具體語法是:
C#中if語法 | PL/SQL中IF語法 |
if (條件){ //條件結構體 } |
IF 條件 THEN --條件結構體 END IF; |
說明:
① 用IF關鍵字開始,END IF關鍵字結束,注意END IF后面有一個分號。
② 條件部分可以不使用括號,但是必須以關鍵字THEN來標識條件結束,如果條件成立,則執行THEN后到對應END IF之間的語句塊內容。如果條件不成立,則不執行條件語句塊的內容。
③ C#結構用一對大括號來包含條件結構體的內容。PL/SQL中關鍵字THEN到END IF之間的內容是條件結構體內容。
④ 條件可以使用關系運算符和邏輯運算符。
案例1:查詢JAMES的工資,如果大於900元,則發獎金800元。
代碼演示:IF-THEN應用
DECLARE newSal emp.sal % TYPE; BEGIN SELECT sal INTO newSal FROM emp WHERE ename='JAMES'; IF newSal>900 THEN ① UPDATE emp SET comm=800 WHERE ename='JAMES'; END IF; COMMIT ; ② END;
代碼解析:
① 先判斷條件,如果條件為TRUE,則執行條件結構體內部的內容。
② 在PL/SQL塊中可以使用事務控制語句,該COMMIT同時也能把PL/SQL塊外沒有提交的數據一並提交,使用時需要注意。
★IF-THEN-ELSE
語法格式:IF-THEN-ELSE
C#中if語法 | PL/SQL中IF語法 |
if (條件){ //條件成立結構體 } else{ //條件不成立結構體 } |
IF 條件 THEN --條件成立結構體 ELSE --條件不成立結構體 END IF; |
語法解析:
把ELSE與IF-THEN連在一起使用,如果IF條件不成立則執行就會執行ELSE部分的語句。
案例2:查詢JAMES的工資,如果大於900元,則發獎金800元,否則發獎金400元。
代碼演示:IF-THEN-ELSE應用
DECLARE newSal emp.sal % TYPE; BEGIN SELECT sal INTO newSal FROM emp WHERE ename='JAMES'; IF newSal>900 THEN UPDATE emp SET comm=800 WHERE ename='JAMES'; ELSE UPDATE emp SET comm=400 WHERE ename='JAMES'; END IF; END;
★IF-THEN-ELSIF
C#中if語法 | PL/SQL中IF語法 |
if (條件2){ //條件成立結構體 } else if(條件2){ //條件不成立結構體 } else{ //以上條件都不成立結構體 } |
IF 條件1 THEN --條件1成立結構體 ELSIF 條件2 THEN --條件2成立結構體 ELSE --以上條件都不成立結構體 END IF; |
語法解析:
PL/SQL中的再次條件判斷中使用關鍵字ELSIF,而C#使用else if。
案例3:查詢JAMES的工資,如果大於1500元,則發放獎金100元,如果工作大於900元,則發獎金800元,否則發獎金400元。
代碼演示:IF-THEN-ELSIF應用
DECLARE newSal emp.sal % TYPE; BEGIN SELECT sal INTO newSal FROM emp WHERE ename='JAMES'; IF newSal>1500 THEN UPDATE emp SET comm=1000 WHERE ename='JAMES'; ELSIF newSal>1500 THEN UPDATE emp SET comm=800 WHERE ename='JAMES'; ELSE
UPDATE emp SET comm=400 WHERE ename='JAMES'; END IF; END;
★CASE
CASE是一種選擇結構的控制語句,可以根據條件從多個執行分支中選擇相應的執行動作。也可以作為表達式使用,返回一個值。類似於C#中的switch語句。語法是:
語法格式:CASE
CASE [selector]
WHEN 表達式1 THEN 語句序列1;
WHEN 表達式2 THEN 語句序列2;
WHEN 表達式3 THEN 語句序列3;
……
[ELSE 語句序列N];
END CASE;
語法解析:
如果存在選擇器selector,選擇器selector與WHEN后面的表達式匹配,匹配成功就執行THEN后面的語句。如果所有表達式都與selector不匹配,則執行ELSE后面的語句。
案例4:輸入一個字母A、B、C分別輸出對應的級別信息。
代碼演示:CASE中存在selector,不返回值
DECLARE v_grade CHAR(1):=UPPER('&p_grade'); ① BEGIN CASE v_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'); ELSE dbms_output.put_line('No such grade'); END CASE; END;
代碼解析:
① & grade表示在運行時由鍵盤輸入字符串到grade變量中。
② v_grade分別於WHEN后面的值匹配,如果成功就執行WHEN后的程序序列。
CASE語句還可以作為表達式使用,返回一個值。
代碼演示:CASE中存在selector,作為表達式使用
DECLARE v_grade CHAR(1):=UPPER('&grade'); p_grade VARCHAR(20) ; BEGIN
p_grade := ① CASE v_grade
WHEN 'A' THEN 'Excellent'
WHEN 'B' THEN 'Very Good' WHEN 'C' THEN 'Good' ELSE 'No such grade'
END; bms_output.put_line('Grade:' ||v_grade||',the result is '||p_grade); END;
代碼解析:
① CASE語句可以返回一個結果給變量p_grade
PL/SQL還提供了搜索CASE語句。也就是說,不使用CASE中的選擇器,直接在WHEN后面判斷條件,第一個條件為真時,執行對應THEN后面的語句序列。
代碼演示:搜索CASE
DECLARE v_grade CHAR(1):=UPPER('&grade'); p_grade VARCHAR(20) ; BEGIN p_grade := CASE WHEN v_grade='A' THEN 'Excellent' WHEN v_grade='B' THEN 'Very Good' WHEN v_grade='C' THEN 'Good' ELSE 'No such grade' END; dbms_output.put_line('Grade:' ||v_grade||',the result is '||p_grade);
END;
※循環結構
PL/SQL提供了豐富的循環結構來重復執行一些列語句。Oracle提供的循環類型有:
1. 無條件循環LOOP-END LOOP語句
2. WHILE循環語句
3. FOR循環語句
在上面的三類循環中EXIT用來強制結束循環,相當於C#循環中的break。
★LOOP循環
LOOP循環是最簡單的循環,也稱為無限循環,LOOP和END LOOP是關鍵字。
語法格式:LOOP循環
LOOP
--循環體
END LOOP;
語法格式:
1. 循環體在LOOP和END LOOP之間,在每個LOOP循環體中,首先執行循環體中的語句序列,執行完后再重新開始執行。
2. 在LOOP循環中可以使用EXIT或者[EXIT WHEN 條件]的形式終止循環。否則該循環就是死循環。
案例5:執行1+2+3+…+100的值
代碼演示:LOOP循環
DECLARE counter number(3):=0; sumResult number:=0; BEGIN LOOP counter := counter+1; sumResult := sumResult+counter; IF counter>=100 THEN ① EXIT; END IF; -- EXIT WHEN counter>=100; ② END LOOP; dbms_output.put_line('result is :'||to_char(sumResult)); END;
代碼解析:
① LOOP循環中可以使用IF結構嵌套EXIT關鍵字退出循環
② 注釋行,該行可以代替①中的循環結構,WHEN后面的條件成立時跳出循環。
★WHILE循環
與C#中的while循環很類似。先判斷條件,條件成立再執行循環體。
語法格式:WHILE
C#中while語法 | PL/SQL中WHILE語法 |
while (條件){ //循環體體 } |
WHILE 條件 LOOP --循環體 END LOOP; |
案例6:WHILE循環
代碼演示:WHILE循環
DECLARE counter number(3):=0; sumResult number:=0; BEGIN WHILE counter<100 LOOP counter:=counter+1; sumResult:=sumResult+counter; END LOOP; dbms_output.put_line('result is :'||sumResult); END
★FOR循環
FOR循環需要預先確定的循環次數,可通過給循環變量指定下限和上限來確定循環運行的次數,然后循環變量在每次循環中遞增(或者遞減)。FOR循環的語法是:
語法格式:FOR循環
FOR 循環變量 IN [REVERSE] 循環下限..循環上限 LOOP LOOP --循環體 END LOOP;
語法解析:
循環變量:該變量的值每次循環根據上下限的REVERSE關鍵字進行加1或者減1。
REVERSE:指明循環從上限向下限依次循環。
案例7:FOR循環
代碼演示:FOR循環
DECLARE counter number(3):=0; sumResult number:=0: BEGIN FOR counter IN 1..100 LOOP sumResult := sumResult+counter; END LOOP; dbms_output.put_line('result is :'||sumResult); END;
※順序結構
在程序順序結構中有兩個特殊的語句。GOTO和NULL
★GOTO語句
GOTO語句將無條件的跳轉到標簽指定的語句去執行。標簽是用雙尖括號括起來的標示符,在PL/SQL塊中必須具有唯一的名稱,標簽后必須緊跟可執行語句或者PL/SQL塊。GOTO不能跳轉到IF語句、CASE語句、LOOP語句、或者子塊中。
★NULL語句
NULL語句什么都不做,只是將控制權轉到下一行語句。NULL語句是可執行語句。NULL語句在IF或者其他語句語法要求至少需要一條可執行語句,但又不需要具體操作的地方。比如GOTO的目標地方不需要執行任何語句時。
案例8:GOGO 和 NULL
代碼演示:GOTO和NULL
DECLARE sumsal emp.sal@TYPE; BEGIN SELECT SUM(sal) INTO sumal FROM EMP; IF sumsal>20000 THEN GOTO first_label;① ELSE GOTO second_label;② END IF; <<first_label>>③ dbms_output.put_line('ABOVE 20000:'||sumsal); <<second_label>>④ NULL; END;
代碼解析:
① 跳轉到程序first_label位置,就是②的位置,first_label是一個標簽,用兩個尖括號包含。
② 無條件跳轉到sedond_label位置,就是④的位置。④處不執行任何內容,因此是一個NULL語句。
與C#一樣,在PL/SQL中,各種循環之間可以相互嵌套。