[
推薦
]
ORACLE?PL/SQL
編程詳解之
三
:
PL/SQL
流程控制語(yǔ)句
(
不給規(guī)則
,
不成方圓
)
——
通過(guò)知識(shí)共享樹立個(gè)人品牌。
繼上
五
篇:
???
[
頂
]ORACLE?PL/SQL
編程詳解之二:
PL/SQL
塊結(jié)構(gòu)和組成元素
(
為山九仞,豈一日之功
)
??? [ 推薦 ]ORACLE?PL/SQL 編程之四:把游標(biāo)說(shuō)透 ( 不怕做不到,只怕想不到 )
?
???? [ 推薦 ]ORACLE?PL/SQL 編程之五:異常錯(cuò)誤處理 ( 知已知彼、百戰(zhàn)不殆 )
?? ? ORACLE?PL/SQL 編程之六:把過(guò)程與函數(shù)說(shuō)透 ( 窮追猛打,把根兒都拔起 !)? ?
?
?????
ORACLE?PL/SQL
編程之八:把觸發(fā)器說(shuō)透
?
接下來(lái) 再次 介紹PL/SQL的基礎(chǔ)篇:PL/SQL流程控制語(yǔ)句,還望大家繼續(xù)支持與推薦~!
?
本篇主要內(nèi)容如下:
?
介紹
PL/SQL
的流程控制語(yǔ)句
,?
包括如下三類
:
l?
控制語(yǔ)句
:?IF?
語(yǔ)句
l?
循環(huán)語(yǔ)句
:?LOOP
語(yǔ)句
,?EXIT
語(yǔ)句
l? 順序語(yǔ)句 :?GOTO 語(yǔ)句 ,?NULL 語(yǔ)句
3.1??
條件語(yǔ)句
?
??PL / SQL?和?SQL語(yǔ)句
END ? IF ;
-- ---------------------
IF ? < 布爾表達(dá)式 > ? THEN
??PL / SQL?和?SQL語(yǔ)句
ELSE
??其它語(yǔ)句
END ? IF ;
-- ---------------------
IF ? < 布爾表達(dá)式 > ? THEN
??PL / SQL?和?SQL語(yǔ)句
ELSIF? < ?其它布爾表達(dá)式 > ? THEN
??其它語(yǔ)句
ELSIF? < ?其它布爾表達(dá)式 > ? THEN
??其它語(yǔ)句
ELSE
??其它語(yǔ)句
END ? IF ;
?
?
提示
:?ELSIF?
不能寫成?
ELSEIF
例
1:
?
????v_empno??employees.employee_id % TYPE?: =& empno;
????V_salary?employees.salary % TYPE;
????V_comment? VARCHAR2 ( 35 );
BEGIN
??? SELECT ?salary? INTO ?v_salary? FROM ?employees?
??? WHERE ?employee_id? = ?v_empno;
??? IF ?v_salary? < ? 1500 ? THEN
???????V_comment: = ? ' 太少了,加點(diǎn)吧~! ' ;
???ELSIF?v_salary? < 3000 ? THEN
??????V_comment: = ? ' 多了點(diǎn),少點(diǎn)吧~! ' ;
??? ELSE
??????V_comment: = ? ' 沒(méi)有薪水~! ' ;
??? END ? IF ;
???DBMS_OUTPUT.PUT_LINE(V_comment);
???exception
????? when ?no_data_found? then
????????DBMS_OUTPUT.PUT_LINE( ' 沒(méi)有數(shù)據(jù)~! ' );
????? when ?others? then
????????DBMS_OUTPUT.PUT_LINE(sqlcode? || ? ' --- ' ? || ?sqlerrm);????????
END ;
?
?
例
2
:
?
???v_first_name?? VARCHAR2 ( 20 );
???v_salary? NUMBER ( 7 , 2 );
BEGIN
??? SELECT ?first_name,?salary? INTO ?v_first_name,?v_salary? FROM ?employees
??? WHERE ?employee_id? = ? & emp_id;
???DBMS_OUTPUT.PUT_LINE(v_first_name || ' 雇員的工資是 ' || v_salary);
??? IF ?v_salary? < ? 10000 ? THEN
??????DBMS_OUTPUT.PUT_LINE( ' 工資低于10000 ' );
??? ELSE
?????? IF ? 10000 ? <= ?v_salary? AND ?v_salary? < ? 20000 ? THEN
?????????DBMS_OUTPUT.PUT_LINE( ' 工資在10000到20000之間 ' );
?????? ELSE
?????????DBMS_OUTPUT.PUT_LINE( ' 工資高于20000 ' );
?????? END ? IF ;
??? END ? IF ;
END ;
?
?
例
3
:
DECLARE
???v_first_name??
VARCHAR2
(
20
);
???v_hire_date?DATE;
???v_bonus?
NUMBER
(
6
,
2
);
BEGIN
???
SELECT
?first_name,?hire_date?
INTO
?v_first_name,?v_hire_date?
FROM
?employees
???
WHERE
?employee_id?
=
?
&
emp_id;
???
IF
?v_hire_date?
>
?TO_DATE(
'
01-1月-90
'
)?
THEN
??????v_bonus?:
=
?
800
;
???ELSIF?v_hire_date?
>
?TO_DATE(
'
01-1月-88
'
)?
THEN
??????v_bonus?:
=
?
1600
;
???
ELSE
??????v_bonus?:
=
?
2400
;
???
END
?
IF
;
???DBMS_OUTPUT.PUT_LINE(v_first_name
||
'
雇員的雇傭日期是
'
||
v_hire_date
????????????????????????????????????
||
'
、獎(jiǎng)金是
'
||
v_bonus);
END
;
???v_first_name?? VARCHAR2 ( 20 );
???v_hire_date?DATE;
???v_bonus? NUMBER ( 6 , 2 );
BEGIN
??? SELECT ?first_name,?hire_date? INTO ?v_first_name,?v_hire_date? FROM ?employees
??? WHERE ?employee_id? = ? & emp_id;
??? IF ?v_hire_date? > ?TO_DATE( ' 01-1月-90 ' )? THEN
??????v_bonus?: = ? 800 ;
???ELSIF?v_hire_date? > ?TO_DATE( ' 01-1月-88 ' )? THEN
??????v_bonus?: = ? 1600 ;
??? ELSE
??????v_bonus?: = ? 2400 ;
??? END ? IF ;
???DBMS_OUTPUT.PUT_LINE(v_first_name || ' 雇員的雇傭日期是 ' || v_hire_date
???????????????????????????????????? || ' 、獎(jiǎng)金是 ' || v_bonus);
END ;
?
3.2??CASE?
表達(dá)式
?
CASE ?條件表達(dá)式
?? WHEN ?條件表達(dá)式結(jié)果1? THEN ?
?????語(yǔ)句段1
?? WHEN ?條件表達(dá)式結(jié)果2? THEN
?????語(yǔ)句段2
??......
?? WHEN ?條件表達(dá)式結(jié)果n? THEN
?????語(yǔ)句段n
?? [ ELSE?條件表達(dá)式結(jié)果 ]
END ;
-- -------格式二---------
CASE ?
?? WHEN ?條件表達(dá)式1? THEN
?????語(yǔ)句段1
?? WHEN ?條件表達(dá)式2? THEN
?????語(yǔ)句段2
??......
?? WHEN ?條件表達(dá)式n? THEN ?
?????語(yǔ)句段n
?? [ ELSE?語(yǔ)句段 ]
END ;
?
?
例
4
:
?
??V_grade? char ( 1 )?: = ? UPPER ( ' &p_grade ' );
??V_appraisal? VARCHAR2 ( 20 );
BEGIN
??V_appraisal?: =
?? CASE ?v_grade
???? WHEN ? ' A ' ? THEN ? ' Excellent '
???? WHEN ? ' B ' ? THEN ? ' Very?Good '
???? WHEN ? ' C ' ? THEN ? ' Good '
???? ELSE ? ' No?such?grade '
?? END ;
??DBMS_OUTPUT.PUT_LINE( ' Grade: ' || v_grade || ' ??Appraisal:? ' || ?v_appraisal);
END ;
?
?
例
5:
?
???v_first_name?employees.first_name % TYPE;
???v_job_id?employees.job_id % TYPE;
???v_salary?employees.salary % TYPE;
???v_sal_raise? NUMBER ( 3 , 2 );
BEGIN
??? SELECT ?first_name,???job_id,???salary? INTO
??????????v_first_name,?v_job_id,?v_salary
??? FROM ?employees? WHERE ?employee_id? = ? & emp_id;
??? CASE
?????? WHEN ?v_job_id? = ? ' PU_CLERK ' ? THEN
????????? IF ?v_salary? < ? 3000 ? THEN ?v_sal_raise?: = ?. 08 ;
????????? ELSE ?v_sal_raise?: = ?. 07 ;
????????? END ? IF ;
?????? WHEN ?v_job_id? = ? ' SH_CLERK ' ? THEN
????????? IF ?v_salary? < ? 4000 ? THEN ?v_sal_raise?: = ?. 06 ;
????????? ELSE ?v_sal_raise?: = ?. 05 ;
????????? END ? IF ;
?????? WHEN ?v_job_id? = ? ' ST_CLERK ' ? THEN
????????? IF ?v_salary? < ? 3500 ? THEN ?v_sal_raise?: = ?. 04 ;
????????? ELSE ?v_sal_raise?: = ?. 03 ;
????????? END ? IF ;
?????? ELSE
?????????DBMS_OUTPUT.PUT_LINE( ' 該崗位不漲工資:? ' || v_job_id);
??? END ? CASE ;
???DBMS_OUTPUT.PUT_LINE(v_first_name || ' 的崗位是 ' || v_job_id
???????????????????????????????????? || ' 、的工資是 ' || v_salary
???????????????????????????????????? || ' 、工資漲幅是 ' || v_sal_raise);
END ;
?
?
?
3.3??
循環(huán)
?1.??
簡(jiǎn)單循環(huán)
?
??????要執(zhí)行的語(yǔ)句;
?????? EXIT ? WHEN ? < 條件語(yǔ)句 > ? -- 條件滿足,退出循環(huán)語(yǔ)句
?? END ?LOOP;
?
?
例?
6
.
?
???? int ? NUMBER ( 2 )?: = 0 ;
BEGIN
???LOOP
?????? int ?: = ? int ? + ? 1 ;
??????DBMS_OUTPUT.PUT_LINE( ' int?的當(dāng)前值為: ' || int );
?????? EXIT ? WHEN ? int ? = 10 ;
??? END ?LOOP;
END ;
?
?
2.??WHILE? 循環(huán)
????要執(zhí)行的語(yǔ)句;
END ?LOOP;
?
例
7
.
?
??x? NUMBER ?: = 1 ;
BEGIN
??? WHILE ?x <= 10 ?LOOP
??????DBMS_OUTPUT.PUT_LINE( ' X的當(dāng)前值為: ' || x);
???????x: = ?x + 1 ;
??? END ?LOOP;
END ;
?
?
3.??
數(shù)字式循環(huán)
?
FOR ?循環(huán)計(jì)數(shù)器? IN ? [ ?REVERSE? ] ?下限?..?上限?LOOP
??要執(zhí)行的語(yǔ)句;
END ?LOOP? [ 循環(huán)標(biāo)簽 ] ;
?
?
每循環(huán)一次,循環(huán)變量自動(dòng)加
1
;使用關(guān)鍵字
REVERSE
,循環(huán)變量自動(dòng)減
1
。跟在
IN?REVERSE?
后面的數(shù)字必須是從小到大的順序,而且必須是整數(shù),不能是變量或表達(dá)式??梢允褂?
EXIT?
退出循環(huán)。
例
8
.
?
??? FOR ? int ?? in ? 1 .. 10 ?LOOP
???????DBMS_OUTPUT.PUT_LINE( ' int?的當(dāng)前值為:? ' || int );
??? END ?LOOP;
END ;
?
?
例?
9
.
?
DECLARE
????V_counter? NUMBER ?: = ? 10 ;
BEGIN
??? INSERT ? INTO ?temp_table(num_col)? VALUES ?(v_counter?);
??? FOR ?v_counter? IN ? 20 ?..? 25 ?LOOP
?????? INSERT ? INTO ?temp_table?(num_col?)? VALUES ?(?v_counter?);
??? END ?LOOP;
??? INSERT ? INTO ?temp_table(num_col)? VALUES ?(v_counter?);
??? FOR ?v_counter? IN ? REVERSE ? 20 ?..? 25 ?LOOP
?????? INSERT ? INTO ?temp_table?(num_col?)? VALUES ?(?v_counter?);
??? END ?LOOP;
END ?;
DROP ? TABLE ?temp_table;
?
?
例
10:
?
???TYPE?jobids_varray? IS ?VARRAY( 12 )? OF ? VARCHAR2 ( 10 );? -- 定義一個(gè)VARRAY數(shù)據(jù)類型
???v_jobids?JOBIDS_VARRAY;? -- 聲明一個(gè)具有JOBIDS_VARRAY數(shù)據(jù)類型的變量
???v_howmany? NUMBER ;? -- 聲明一個(gè)變量來(lái)保存雇員的數(shù)量
BEGIN
??? -- 用某些job_id值初始化數(shù)組
???v_jobids?: = ?jobids_varray( ' FI_ACCOUNT ' ,? ' FI_MGR ' ,? ' ST_CLERK ' ,? ' ST_MAN ' );
??? -- 用FOR...LOOP...END?LOOP循環(huán)使用每個(gè)數(shù)組成員的值
??? FOR ?i? IN ?v_jobids.FIRST..v_jobids.LAST?LOOP
??? -- 針對(duì)數(shù)組中的每個(gè)崗位,決定該崗位的雇員的數(shù)量
?????? SELECT ? count ( * )? INTO ?v_howmany? FROM ?employees? WHERE ?job_id? = ?v_jobids(i);
??????DBMS_OUTPUT.PUT_LINE?(? ' 崗位 ' || v_jobids(i) ||
??????????????????????? ' 總共有 ' || ?TO_CHAR(v_howmany)? || ? ' 個(gè)雇員 ' );
??? END ?LOOP;
END ;
?
?
例
11?
在
While
循環(huán)中嵌套
loop
循環(huán)
/*
求100至110之間的素?cái)?shù)
*/
DECLARE
???v_m?
NUMBER
?:
=
?
101
;
???v_i?
NUMBER
;
???v_n?
NUMBER
?:
=
?
0
;
BEGIN
???
WHILE
?v_m?
<
?
110
?LOOP
??????v_i?:
=
?
2
;
??????LOOP
?????????
IF
?mod(v_m,?v_i)?
=
?
0
?
THEN
????????????v_i?:
=
?
0
;
????????????
EXIT
;
?????????
END
?
IF
;
????
?????????v_i?:
=
?v_i?
+
?
1
;
?????????
EXIT
?
WHEN
?v_i?
>
?v_m?
-
?
1
;?
??????
END
?LOOP;
??????
??????
IF
?v_i?
>
?
0
?
THEN
?????????v_n?:
=
?v_n?
+
?
1
;
?????????DBMS_OUTPUT.PUT_LINE(
'
第
'
||
?v_n?
||
?
'
個(gè)素?cái)?shù)是
'
?
||
?v_m);
??????
END
?
IF
;
??????v_m?:
=
?v_m?
+
?
2
;
???
END
?LOOP;
END
;
DECLARE
???v_m? NUMBER ?: = ? 101 ;
???v_i? NUMBER ;
???v_n? NUMBER ?: = ? 0 ;
BEGIN
??? WHILE ?v_m? < ? 110 ?LOOP
??????v_i?: = ? 2 ;
??????LOOP
????????? IF ?mod(v_m,?v_i)? = ? 0 ? THEN
????????????v_i?: = ? 0 ;
???????????? EXIT ;
????????? END ? IF ;
????
?????????v_i?: = ?v_i? + ? 1 ;
????????? EXIT ? WHEN ?v_i? > ?v_m? - ? 1 ;?
?????? END ?LOOP;
??????
?????? IF ?v_i? > ? 0 ? THEN
?????????v_n?: = ?v_n? + ? 1 ;
?????????DBMS_OUTPUT.PUT_LINE( ' 第 ' || ?v_n? || ? ' 個(gè)素?cái)?shù)是 ' ? || ?v_m);
?????? END ? IF ;
??????v_m?: = ?v_m? + ? 2 ;
??? END ?LOOP;
END ;
?
3.
4
??標(biāo)號(hào)和
GOTO
?
PL/SQL
中
GOTO
語(yǔ)句是無(wú)條件跳轉(zhuǎn)到指定的標(biāo)號(hào)去的意思。語(yǔ)法如下:
?
......
<< label >> /* 標(biāo)號(hào)是用<< >>括起來(lái)的標(biāo)識(shí)符? */
?
?
注意
,在以下地方使用是不合法的,編譯時(shí)會(huì)出錯(cuò)誤。
u?
跳轉(zhuǎn)到非執(zhí)行語(yǔ)句前面。
u?
跳轉(zhuǎn)到子塊中。
u?
跳轉(zhuǎn)到循環(huán)語(yǔ)句中。
u?
跳轉(zhuǎn)到條件語(yǔ)句中。
u?
從異常處理部分跳轉(zhuǎn)到執(zhí)行。
u?
從條件語(yǔ)句的一部分跳轉(zhuǎn)到另一部分。
例
12
:
?
???V_counter? NUMBER ?: = ? 1 ;
BEGIN
???LOOP?
?????DBMS_OUTPUT.PUT_LINE( ' V_counter的當(dāng)前值為: ' || V_counter);
?????V_counter?: = ?v_counter? + ? 1 ;
??? IF ?v_counter? > ? 10 ? THEN
??????? GOTO ?labelOffLOOP;
??? END ? IF ;
??? END ?LOOP;
??? << labelOffLOOP >>
?????DBMS_OUTPUT.PUT_LINE( ' V_counter的當(dāng)前值為: ' || V_counter);
END ;
?
?
例
13:
DECLARE
???v_i?
NUMBER
?:
=
?
0
;
???v_s?
NUMBER
?:
=
?
0
;
BEGIN
???
<<
label_1
>>
???v_i?:
=
?v_i?
+
?
1
;
???
IF
?v_i?
<=
?
1000
?
THEN
??????v_s?:
=
?v_s?
+
?v_i;
??????
GOTO
?label_1;
???
END
?
IF
;
???DBMS_OUTPUT.PUT_LINE(v_s);
END
;
???v_i? NUMBER ?: = ? 0 ;
???v_s? NUMBER ?: = ? 0 ;
BEGIN
??? << label_1 >>
???v_i?: = ?v_i? + ? 1 ;
??? IF ?v_i? <= ? 1000 ? THEN
??????v_s?: = ?v_s? + ?v_i;
?????? GOTO ?label_1;
??? END ? IF ;
???DBMS_OUTPUT.PUT_LINE(v_s);
END ;
?
3.
5
??NULL?
語(yǔ)句
?
在
PL/SQL?
程序中,
NULL
語(yǔ)句是一個(gè)可執(zhí)行語(yǔ)句,
可以用?
null?
語(yǔ)句來(lái)說(shuō)明
“
不用做任何事情
”
的意思,相當(dāng)于一個(gè)占位符
或不執(zhí)行任何操作的空語(yǔ)句
,可以使某些語(yǔ)句變得有意義,提高程序的可讀性
,保證其他語(yǔ)句結(jié)構(gòu)的完整性和正確性
。如:
例
14:
?
????...
BEGIN
????...
???? IF ?v_num? IS ? NULL ? THEN
???? GOTO ?labelPrint;
???? END ? IF ;
??…
?? << labelPrint >>
?? NULL ;? -- 不需要處理任何數(shù)據(jù)。
END ;
?
例 15:
?
???v_emp_id?employees.employee_id % TYPE;
???v_first_name?employees.first_name % TYPE;
???v_salary?employees.salary % TYPE;
???v_sal_raise? NUMBER ( 3 , 2 );
BEGIN
???v_emp_id?: = ? & emp_id;
??? SELECT ?first_name,?salary? INTO ?v_first_name,?v_salary
??? FROM ?employees? WHERE ?employee_id? = ?v_emp_id;
??? IF ?v_salary? <= ? 3000 ? THEN
??????v_sal_raise?: = ?. 10 ;
??????DBMS_OUTPUT.PUT_LINE(v_first_name || ' 的工資是 ' || v_salary
??????????????????????????????????????? || ' 、工資漲幅是 ' || v_sal_raise);
??? ELSE
?????? NULL ;
??? END ? IF ;
END ;
?
??2011??
EricHu
原創(chuàng)作品,轉(zhuǎn)貼請(qǐng)注明作者和出處,留此信息。
------------------------------------------------
cnBlobs:
http://www.cnblogs.com/huyong/
CSDN
:
http://blog.csdn.net/chinahuyong
?
作者:
EricHu
(
DB
、
C\S
、
B\S
、
WebService
、
WCF
、
PM
等
)
出處:
http://
www
.cnblogs.com
/huyong/
Q?Q
:
80368704???E-Mail:?80368704@qq.com
本博文歡迎大家瀏覽和轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面明顯位置給出原文連接,在『參考』的文章中,我會(huì)表明參考的文章來(lái)源,尊重他人版權(quán)。若您發(fā)現(xiàn)我侵犯了您的版權(quán),請(qǐng)及時(shí)與我聯(lián)系。
更多文章請(qǐng)看
?
[
置頂
]
索引貼
——
(不斷更新中)
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
