大家好,又见面了,我是你们的朋友全栈君。
[推荐]Oracle PL/SQL编程详解之三:
PL/SQL流程控制语句(不给规则,不成方圆)
本篇主要内容如下:
介绍PL/SQL的流程控制语句, 包括如下三类:
l 控制语句: IF 语句
l 循环语句: LOOP语句, EXIT语句
l 顺序语句: GOTO语句, NULL语句
3.1 条件语句
<
布尔表达式
>
THEN
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 循环
<
布尔表达式
>
LOOP
要执行的语句;
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.
TABLE
temp_table(num_col
NUMBER
);
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
;
求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
;
3.4 标号和GOTO
PL/SQL中GOTO语句是无条件跳转到指定的标号去的意思。语法如下:
label;
……
<<
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
本博文欢迎大家浏览和转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,在『参考』的文章中,我会表明参考的文章来源,尊重他人版权。若您发现我侵犯了您的版权,请及时与我联系。
更多文章请看 [置顶]索引贴——(不断更新中)
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/149558.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...