[
推荐
]
ORACLE PL/SQL
编程详解之
三
:
PL/SQL
流程控制语句
(
不给规则
,
不成方圆
)
——
通过知识共享树立个人品牌。
继上
五
篇:
[
顶
]ORACLE PL/SQL
编程详解之二:
PL/SQL
块结构和组成元素
(
为山九仞,岂一日之功
)
[ 推荐 ]ORACLE PL/SQL 编程之四:把游标说透 ( 不怕做不到,只怕想不到 )
[ 推荐 ]ORACLE PL/SQL 编程之五:异常错误处理 ( 知已知彼、百战不殆 )
ORACLE PL/SQL 编程之六:把过程与函数说透 ( 穷追猛打,把根儿都拔起 !)
接下来 再次 介绍PL/SQL的基础篇:PL/SQL流程控制语句,还望大家继续支持与推荐~!
本篇主要内容如下:
介绍
PL/SQL
的流程控制语句
,
包括如下三类
:
l
控制语句
: IF
语句
l
循环语句
: LOOP
语句
, EXIT
语句
l 顺序语句 : GOTO 语句 , NULL 语句
3.1
条件语句
PL / SQL 和 SQL语句
END IF ;
-- ---------------------
IF < 布尔表达式 > THEN
PL / SQL 和 SQL语句
ELSE
其它语句
END IF ;
-- ---------------------
IF < 布尔表达式 > THEN
PL / SQL 和 SQL语句
ELSIF < 其它布尔表达式 > THEN
其它语句
ELSIF < 其它布尔表达式 > THEN
其它语句
ELSE
其它语句
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: = ' 太少了,加点吧~! ' ;
ELSIF v_salary < 3000 THEN
V_comment: = ' 多了点,少点吧~! ' ;
ELSE
V_comment: = ' 没有薪水~! ' ;
END IF ;
DBMS_OUTPUT.PUT_LINE(V_comment);
exception
when no_data_found then
DBMS_OUTPUT.PUT_LINE( ' 没有数据~! ' );
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
||
'
、奖金是
'
||
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
|| ' 、奖金是 ' || v_bonus);
END ;
3.2 CASE
表达式
CASE 条件表达式
WHEN 条件表达式结果1 THEN
语句段1
WHEN 条件表达式结果2 THEN
语句段2
......
WHEN 条件表达式结果n THEN
语句段n
[ ELSE 条件表达式结果 ]
END ;
-- -------格式二---------
CASE
WHEN 条件表达式1 THEN
语句段1
WHEN 条件表达式2 THEN
语句段2
......
WHEN 条件表达式n THEN
语句段n
[ ELSE 语句段 ]
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
循环
1.
简单循环
要执行的语句;
EXIT WHEN < 条件语句 > -- 条件满足,退出循环语句
END LOOP;
例
6
.
int NUMBER ( 2 ) : = 0 ;
BEGIN
LOOP
int : = int + 1 ;
DBMS_OUTPUT.PUT_LINE( ' int 的当前值为: ' || int );
EXIT WHEN int = 10 ;
END LOOP;
END ;
2. WHILE 循环
要执行的语句;
END LOOP;
例
7
.
x NUMBER : = 1 ;
BEGIN
WHILE x <= 10 LOOP
DBMS_OUTPUT.PUT_LINE( ' X的当前值为: ' || x);
x: = x + 1 ;
END LOOP;
END ;
3.
数字式循环
FOR 循环计数器 IN [ REVERSE ] 下限 .. 上限 LOOP
要执行的语句;
END LOOP [ 循环标签 ] ;
每循环一次,循环变量自动加
1
;使用关键字
REVERSE
,循环变量自动减
1
。跟在
IN REVERSE
后面的数字必须是从小到大的顺序,而且必须是整数,不能是变量或表达式。可以使用
EXIT
退出循环。
例
8
.
FOR int in 1 .. 10 LOOP
DBMS_OUTPUT.PUT_LINE( ' int 的当前值为: ' || 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 ); -- 定义一个VARRAY数据类型
v_jobids JOBIDS_VARRAY; -- 声明一个具有JOBIDS_VARRAY数据类型的变量
v_howmany NUMBER ; -- 声明一个变量来保存雇员的数量
BEGIN
-- 用某些job_id值初始化数组
v_jobids : = jobids_varray( ' FI_ACCOUNT ' , ' FI_MGR ' , ' ST_CLERK ' , ' ST_MAN ' );
-- 用FOR...LOOP...END LOOP循环使用每个数组成员的值
FOR i IN v_jobids.FIRST..v_jobids.LAST LOOP
-- 针对数组中的每个岗位,决定该岗位的雇员的数量
SELECT count ( * ) INTO v_howmany FROM employees WHERE job_id = v_jobids(i);
DBMS_OUTPUT.PUT_LINE ( ' 岗位 ' || v_jobids(i) ||
' 总共有 ' || TO_CHAR(v_howmany) || ' 个雇员 ' );
END LOOP;
END ;
例
11
在
While
循环中嵌套
loop
循环
/*
求100至110之间的素数
*/
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
||
'
个素数是
'
||
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 || ' 个素数是 ' || v_m);
END IF ;
v_m : = v_m + 2 ;
END LOOP;
END ;
3.
4
标号和
GOTO
PL/SQL
中
GOTO
语句是无条件跳转到指定的标号去的意思。语法如下:
......
<< label >> /* 标号是用<< >>括起来的标识符 */
注意
,在以下地方使用是不合法的,编译时会出错误。
u
跳转到非执行语句前面。
u
跳转到子块中。
u
跳转到循环语句中。
u
跳转到条件语句中。
u
从异常处理部分跳转到执行。
u
从条件语句的一部分跳转到另一部分。
例
12
:
V_counter NUMBER : = 1 ;
BEGIN
LOOP
DBMS_OUTPUT.PUT_LINE( ' V_counter的当前值为: ' || 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的当前值为: ' || 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
语句
在
PL/SQL
程序中,
NULL
语句是一个可执行语句,
可以用
null
语句来说明
“
不用做任何事情
”
的意思,相当于一个占位符
或不执行任何操作的空语句
,可以使某些语句变得有意义,提高程序的可读性
,保证其他语句结构的完整性和正确性
。如:
例
14:
...
BEGIN
...
IF v_num IS NULL THEN
GOTO labelPrint;
END IF ;
…
<< labelPrint >>
NULL ; -- 不需要处理任何数据。
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
原创作品,转贴请注明作者和出处,留此信息。
------------------------------------------------
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
本博文欢迎大家浏览和转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,在『参考』的文章中,我会表明参考的文章来源,尊重他人版权。若您发现我侵犯了您的版权,请及时与我联系。
更多文章请看
[
置顶
]
索引贴
——
(不断更新中)