分支結(jié)構(gòu) 分支結(jié)構(gòu)是最基本的程序結(jié)構(gòu),分支結(jié)構(gòu)由IF語(yǔ)句實(shí)現(xiàn)。
使用IF語(yǔ)句,根據(jù)條件可以改變程序的邏輯流程。IF語(yǔ)句有如下的形式:
IF 條件1 THEN
語(yǔ)句序列1;
[ELSIF 條件2 THEN
語(yǔ)句序列2;
ELSE
語(yǔ)句序列n;]
END IF;
其中:
條件部分是一個(gè)邏輯表達(dá)式,值只能是真(TRUE)、假(FALSE)或空(NULL)。
語(yǔ)句序列為多條可執(zhí)行的語(yǔ)句。
根據(jù)具體情況,分支結(jié)構(gòu)可以有以下幾種形式:
IF-THEN-END IF
IF-THEN-ELSE-END IF
IF-THEN-ELSIF-ELSE-END IF
1.IF-THEN-END IF形式
這是最簡(jiǎn)單的IF結(jié)構(gòu),練習(xí)如下:
【訓(xùn)練1】 如果溫度大于30℃,則顯示“溫度偏高”。
輸入并執(zhí)行以下程序:
- SET SERVEROUTPUT ON
- DECLARE
- V_temprature NUMBER(5):=32;
- V_result BOOLEAN:=false;
- BEGIN
- V_result:= v_temprature >30;
- IF V_result THEN
- DBMS_OUTPUT.PUT_LINE('溫度'|| V_temprature ||'度,偏高');
- END IF;
- END;
執(zhí)行結(jié)果為:
- 溫度32度,偏高
- PL/SQL過(guò)程已成功完成。
說(shuō)明:該程序中使用了布爾變量,初值為false,表示溫度低于30℃。表達(dá)式v_temprature >30返回值為布爾型,賦給邏輯變量V_result。如果變量v_temprature的值大于30,則返回值為真,否則為假。V_result值為真就會(huì)執(zhí)行IF到 END IF之間的輸出語(yǔ)句,否則沒(méi)有輸出結(jié)果。
試修改溫度的初值為25℃,重新執(zhí)行,觀察結(jié)果。
2.IF-THEN-ELSE-END IF形式
這種形式的練習(xí)如下:
【訓(xùn)練2】 根據(jù)性別,顯示尊稱。
輸入并執(zhí)行以下程序:
- SET SERVEROUTPUT ON
- DECLARE
- v_sex VARCHAR2(2);
- v_titil VARCHAR2(10);
- BEGIN
- v_sex:='男';
- IF v_sex ='男' THEN
- v_titil:='先生';
- ELSE
- v_titil:='女士';
- END IF;
- DBMS_OUTPUT.PUT_LINE(v_titil||'您好!');
- END;
執(zhí)行結(jié)果為:
- 先生您好!
- PL/SQL 過(guò)程已成功完成。
說(shuō)明:該程序根據(jù)性別顯示尊稱和問(wèn)候,無(wú)論性別的值為何,總會(huì)有顯示結(jié)果輸出。如果V_sex的值不是‘男’和‘女’,那么輸出結(jié)果會(huì)是什么?
【練習(xí)1】對(duì)以上程序進(jìn)行補(bǔ)充修改,在ELSE部分嵌入一個(gè)IF結(jié)構(gòu),如果V_sex的值不是'女',則顯示“朋友你好”。
3.IF-THEN-ELSIF-ELSE-END IF形式
這種形式的練習(xí)如下:
【訓(xùn)練3】 根據(jù)雇員工資分級(jí)顯示稅金。
輸入并運(yùn)行以下程序:
- SET SERVEROUTPUT ON
- DECLARE
- v_sal NUMBER(5);
- v_tax NUMBER(5,2);
- BEGIN
- SELECT sal INTO v_sal
- FROM emp
- WHERE empno=7788;
- IF v_sal >=3000 THEN
- V_tax:= v_sal*0.08;--稅率8%
- ELSIF v_sal>=1500 THEN
- V_tax:= v_sal*0.06; --稅率6%
- ELSE
- V_tax:= v_sal*0.04; --稅率4%
- END IF;
- DBMS_OUTPUT.PUT_LINE('應(yīng)繳稅金:'||V_tax);
- END;
執(zhí)行結(jié)果為:
- 應(yīng)繳稅金:240
- PL/SQL 過(guò)程已成功完成。
說(shuō)明:該程序根據(jù)工資計(jì)算7788號(hào)雇員應(yīng)繳稅金,不同工資級(jí)別的稅率不同。
選擇結(jié)構(gòu) CASE語(yǔ)句適用于分情況的多分支處理,可有以下三種用法。
1.基本CASE結(jié)構(gòu)
語(yǔ)句的語(yǔ)法如下:
CASE 選擇變量名
WHEN 表達(dá)式1 THEN
語(yǔ)句序列1
WHEN 表達(dá)式2 THEN
語(yǔ)句序列2
WHEN 表達(dá)式n THEN
語(yǔ)句序列n
ELSE
語(yǔ)句序列n+1
END CASE;
在整個(gè)結(jié)構(gòu)中,選擇變量的值同表達(dá)式的值進(jìn)行順序匹配,如果相等,則執(zhí)行相應(yīng)的語(yǔ)句序列,如果不等,則執(zhí)行ELSE部分的語(yǔ)句序列。
以下是一個(gè)使用CASE選擇結(jié)構(gòu)的練習(xí)。
【訓(xùn)練1】 使用CASE結(jié)構(gòu)實(shí)現(xiàn)職務(wù)轉(zhuǎn)換。
輸入并執(zhí)行程序:
- SET SERVEROUTPUT ON
- DECLARE
- v_job VARCHAR2(10);
- BEGIN
- SELECT job INTO v_job
- FROM emp
- WHERE empno=7788;
- CASE v_job
- WHEN 'PRESIDENT' THEN
- DBMS_OUTPUT.PUT_LINE('雇員職務(wù):總裁');
- WHEN 'MANAGER' THEN
- DBMS_OUTPUT.PUT_LINE('雇員職務(wù):經(jīng)理');
- WHEN 'SALESMAN' THEN
- DBMS_OUTPUT.PUT_LINE('雇員職務(wù):推銷員');
- WHEN 'ANALYST' THEN
- DBMS_OUTPUT.PUT_LINE('雇員職務(wù):系統(tǒng)分析員');
- WHEN 'CLERK' THEN
- DBMS_OUTPUT.PUT_LINE('雇員職務(wù):職員');
- ELSE
- DBMS_OUTPUT.PUT_LINE('雇員職務(wù):未知');
- END CASE;
- END;
執(zhí)行結(jié)果:
- 雇員職務(wù):系統(tǒng)分析員
- PL/SQL 過(guò)程已成功完成。
說(shuō)明:以上實(shí)例檢索雇員7788的職務(wù),通過(guò)CASE結(jié)構(gòu)轉(zhuǎn)換成中文輸出。
【練習(xí)1】將雇員號(hào)修改成其他已知雇員號(hào),重新執(zhí)行。
2.表達(dá)式結(jié)構(gòu)CASE語(yǔ)句
在Oracle中,CASE結(jié)構(gòu)還能以賦值表達(dá)式的形式出現(xiàn),它根據(jù)選擇變量的值求得不同的結(jié)果。
它的基本結(jié)構(gòu)如下:
變量=CASE 選擇變量名
WHEN 表達(dá)式1 THEN 值1
WHEN 表達(dá)式2 THEN 值2
WHEN 表達(dá)式n THEN 值n
ELSE值n+1
END;
【訓(xùn)練2】 使用CASE的表達(dá)式結(jié)構(gòu)。
- SET SERVEROUTPUT ON
- DECLARE
- v_grade VARCHAR2(10);
- v_result VARCHAR2(10);
- BEGIN
- v_grade:='B';
- v_result:=CASE v_grade
- WHEN 'A' THEN '優(yōu)'
- WHEN 'B' THEN '良'
- WHEN 'C' THEN '中'
- WHEN 'D' THEN '差'
- ELSE '未知'
- END;
- DBMS_OUTPUT.PUT_LINE('評(píng)價(jià)等級(jí):'||V_result);
- END;
執(zhí)行結(jié)果為:
- 評(píng)價(jià)等級(jí):良
- PL/SQL 過(guò)程已成功完成。
說(shuō)明:該CASE表達(dá)式通過(guò)判斷變量v_grade的值,對(duì)變量V_result賦予不同的值。
3.搜索CASE結(jié)構(gòu)
Oracle還提供了一種搜索CASE結(jié)構(gòu),它沒(méi)有選擇變量,直接判斷條件表達(dá)式的值,根據(jù)條件表達(dá)式?jīng)Q定轉(zhuǎn)向。
CASE
WHEN 條件表達(dá)式1 THEN
語(yǔ)句序列1
WHEN 條件表達(dá)式2 THEN
語(yǔ)句序列2
WHEN 條件表達(dá)式n THEN
語(yǔ)句序列n
ELSE
語(yǔ)句序列n+1
END CASE;
【訓(xùn)練3】 使用CASE的搜索結(jié)構(gòu)。
- SET SERVEROUTPUT ON
- DECLARE
- v_sal NUMBER(5);
- BEGIN
- SELECT sal INTO v_sal FROM emp
- WHERE empno=7788;
- CASE
- WHEN v_sal>=3000 THEN
- DBMS_OUTPUT.PUT_LINE('工資等級(jí):高');
- WHEN v_sal>=1500 THEN
- DBMS_OUTPUT.PUT_LINE('工資等級(jí):中');
- ELSE
- DBMS_OUTPUT.PUT_LINE('工資等級(jí):低');
- END CASE;
- END;
執(zhí)行結(jié)果為:
- 工資等級(jí):高
- PL/SQL 過(guò)程已成功完成。
說(shuō)明:此結(jié)構(gòu)類似于IF-THEN-ELSIF-ELSE-END IF結(jié)構(gòu)。本訓(xùn)練判斷7788雇員的工資等級(jí)。
循環(huán)結(jié)構(gòu) 循環(huán)結(jié)構(gòu)是最重要的程序控制結(jié)構(gòu),用來(lái)控制反復(fù)執(zhí)行一段程序。比如我們要進(jìn)行累加,則可以通過(guò)適當(dāng)?shù)难h(huán)程序?qū)崿F(xiàn)。PL/SQL循環(huán)結(jié)構(gòu)可劃分為以下3種:
* 基本LOOP循環(huán)。
* FOR LOOP循環(huán)。
* WHILE LOOP循環(huán)。
1.基本LOOP循環(huán)
基本循環(huán)的結(jié)構(gòu)如下:
LOOP --循環(huán)起始標(biāo)識(shí)
語(yǔ)句1;
語(yǔ)句2;
EXIT [WHEN 條件];
END LOOP; --循環(huán)結(jié)束標(biāo)識(shí)
該循環(huán)的作用是反復(fù)執(zhí)行LOOP與END LOOP之間的語(yǔ)句。
EXIT用于在循環(huán)過(guò)程中退出循環(huán),WHEN用于定義EXIT的退出條件。如果沒(méi)有WHEN條件,遇到EXIT語(yǔ)句則無(wú)條件退出循環(huán)。
【訓(xùn)練1】 求:12+32+52+...+152 的值。
輸入并執(zhí)行以下程序:
- SET SERVEROUTPUT ON
- DECLARE
- v_total NUMBER(5):=0;
- v_count NUMBER(5):=1;
- BEGIN
- LOOP
- v_total:=v_total+v_count**2;
- EXIT WHEN v_count=15;--條件退出
- v_count:=v_count+2;
- END LOOP;
- DBMS_OUTPUT.PUT_LINE(v_total);
- END;
輸出結(jié)果為:
說(shuō)明:基本循環(huán)一定要使用EXIT退出,否則就會(huì)成為死循環(huán)。
【練習(xí)1】求1*2*3*4*...*10的值。
2.FOR LOOP循環(huán)
FOR循環(huán)是固定次數(shù)循環(huán),格式如下:
FOR 控制變量 in [REVERSE] 下限..上限
LOOP
語(yǔ)句1;
語(yǔ)句2;
END LOOP;
循環(huán)控制變量是隱含定義的,不需要聲明。
下限和上限用于指明循環(huán)次數(shù)。正常情況下循環(huán)控制變量的取值由下限到上限遞增,REVERSE關(guān)鍵字表示循環(huán)控制變量的取值由上限到下限遞減。
以下是FOR循環(huán)結(jié)構(gòu)的練習(xí)。
【訓(xùn)練2】 用FOR循環(huán)輸出圖形。
- SET SERVEROUTPUT ON
- BEGIN
- FOR I IN 1..8
- LOOP
- DBMS_OUTPUT.PUT_LINE(to_char(i)||rpad('*',I,'*'));
- END LOOP;
- END;
輸出結(jié)果為:
- 1*
- 2**
- 3***
- 4****
- 5*****
- 6******
- 7*******
- 8********
- PL/SQL 過(guò)程已成功完成。
說(shuō)明:該程序在循環(huán)中使用了循環(huán)控制變量I,該變量隱含定義。在每次循環(huán)中根據(jù)循環(huán)控制變量I的值,使用RPAD函數(shù)控制顯示相應(yīng)個(gè)數(shù)的“*”。
【練習(xí)2】為以上程序增加REVERSE關(guān)鍵字,觀察執(zhí)行結(jié)果。
【訓(xùn)練3】 輸出一個(gè)空心三角形。
- BEGIN
- FOR I IN 1..9
- LOOP
- IF I=1 OR I=9 THEN
- DBMS_OUTPUT.PUT_LINE(to_char(I)||rpad(' ',12-I,' ')||rpad('*',2*i-1,'*'));
- ELSE
- DBMS_OUTPUT.PUT_LINE(to_char(I)||rpad(' ',12-I,' ')||'*'||rpad(' ',I*2-3,' ')||'*');
- END IF;
- END LOOP;
- END;
輸出結(jié)果為:
- 1 *
- 2 * *
- 3 * *
- 4 * *
- 5 * *
- 6 * *
- 7 * *
- 8 * *
- 9 *****************
- PL/SQL 過(guò)程已成功完成。
說(shuō)明:該實(shí)例采用循環(huán)和IF結(jié)構(gòu)相結(jié)合,對(duì)第1行和第9行(I=1 OR I=9)執(zhí)行同樣的輸出語(yǔ)句,其他行執(zhí)行另外的輸出語(yǔ)句。
【練習(xí)3】修改程序,輸出一個(gè)實(shí)心三角形。
3.WHILE LOOP循環(huán)
WHILE循環(huán)是有條件循環(huán),其格式如下:
WHILE 條件
LOOP
語(yǔ)句1;
語(yǔ)句2;
END LOOP;
當(dāng)條件滿足時(shí),執(zhí)行循環(huán)體;當(dāng)條件不滿足時(shí),則結(jié)束循環(huán)。如果第一次判斷條件為假,則不執(zhí)行循環(huán)體。
以下是WHILE循環(huán)結(jié)構(gòu)的練習(xí)。
【訓(xùn)練3】 使用WHILE 循環(huán)向emp表連續(xù)插入5個(gè)記錄。
步驟1:執(zhí)行下面的程序:
- SET SERVEROUTPUT ON
- DECLARE
- v_count NUMBER(2) := 1;
- BEGIN
- WHILE v_count <6 LOOP
- INSERT INTO emp(empno, ename)
- VALUES (5000+v_count, '臨時(shí)');
- v_count := v_count + 1;
- END LOOP;
- COMMIT;
- END;
輸出結(jié)果為:
步驟2:顯示插入的記錄:
- SELECT empno,ename FROM emp WHERE ename='臨時(shí)';
輸出結(jié)果為:
- EMPNO ENAME
- ------------------ ----------
- 5001 臨時(shí)
- 5002 臨時(shí)
- 5003 臨時(shí)
- 5004 臨時(shí)
- 5005 臨時(shí)
- 已選擇5行。
步驟3:刪除插入的記錄:
- DELETE FROM emp WHERE ename='臨時(shí)';
- COMMIT;
輸出結(jié)果為:
說(shuō)明:該練習(xí)使用WHILE循環(huán)向emp表插入5個(gè)新記錄(雇員編號(hào)根據(jù)循環(huán)變量生成),并通過(guò)查詢語(yǔ)句顯示新插入的記錄,然后刪除。
4.多重循環(huán)
循環(huán)可以嵌套,以下是一個(gè)二重循環(huán)的練習(xí)。
【訓(xùn)練4】 使用二重循環(huán)求1!+2!+...+10!的值。
步驟1:第1種算法:
- SET SERVEROUTPUT ON
- DECLARE
- v_total NUMBER(8):=0;
- v_ni NUMBER(8):=0;
- J NUMBER(5);
- BEGIN
- FOR I IN 1..10
- LOOP
- J:=1;
- v_ni:=1;
- WHILE J<=I
- LOOP
- v_ni:= v_ni*J;
- J:=J+1;
- END LOOP;--內(nèi)循環(huán)求n!
- v_total:=v_total+v_ni;
- END LOOP;--外循環(huán)求總和
- DBMS_OUTPUT.PUT_LINE(v_total);
- END;
輸出結(jié)果為:
- 4037913
- PL/SQL 過(guò)程已成功完成。
步驟2:第2種算法:
- SET SERVEROUTPUT ON
- DECLARE
- v_total NUMBER(8):=0;
- v_ni NUMBER(8):=1;
- BEGIN
- FOR I IN 1..10
- LOOP
- v_ni:= v_ni*I; --求n!
- v_total:= v_total+v_ni;
- END LOOP; --循環(huán)求總和
- DBMS_OUTPUT.PUT_LINE(v_total);
- END;
輸出結(jié)果為:
- 409114
- PL/SQL 過(guò)程已成功完成。
說(shuō)明:第1種算法的程序內(nèi)循環(huán)使用WHILE循環(huán)求階層,外循環(huán)使用FOR循環(huán)求總和。第2種算法是簡(jiǎn)化的算法,根據(jù)是:n!=n*(n?1)!。