[推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆)

[推荐]ORACLEPL/SQL编程详解之

PL/SQL流程控制语句(不给规则不成方圆)

——通过知识共享树立个人品牌。

继上篇:

[]ORACLEPL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功)

[推荐]ORACLEPL/SQL编程之四:把游标说透(不怕做不到,只怕想不到)

[推荐]ORACLEPL/SQL编程之五:异常错误处理(知已知彼、百战不殆)

ORACLEPL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!)

ORACLEPL/SQL编程之八:把触发器说透

接下来再次介绍PL/SQL的基础篇:PL/SQL流程控制语句,还望大家继续支持与推荐~!

本篇主要内容如下:

3.1条件语句

3.2CASE表达式

3.3循环

3.4标号和GOTO

3.5NULL语句

介绍PL/SQL的流程控制语句,包括如下三类:

l控制语句:IF语句

l循环语句:LOOP语句,EXIT语句

l顺序语句:GOTO语句,NULL语句

<!--EndFragment-->3.1条件语句

IF < 布尔表达式 > 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:

DECLARE
v_empnoemployees.employee_id
% TYPE: =& empno;
V_salaryemployees.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:
= ' 太少了,加点吧~! ' ;
ELSIFv_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:

DECLARE
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_dateDATE;
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 ;
ELSIFv_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.2CASE表达式

-- -------格式一---------
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:

DECLARE
V_grade
char ( 1 ): = UPPER ( ' &p_grade ' );
V_appraisal
VARCHAR2 ( 20 );
BEGIN
V_appraisal:
=
CASE v_grade
WHEN ' A ' THEN ' Excellent '
WHEN ' B ' THEN ' VeryGood '
WHEN ' C ' THEN ' Good '
ELSE ' Nosuchgrade '
END ;
DBMS_OUTPUT.PUT_LINE(
' Grade: ' || v_grade || ' Appraisal: ' || v_appraisal);
END ;

5:

DECLARE
v_first_nameemployees.first_name
% TYPE;
v_job_idemployees.job_id
% TYPE;
v_salaryemployees.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.简单循环

LOOP
要执行的语句;
EXIT WHEN < 条件语句 > -- 条件满足,退出循环语句
END LOOP;

6.

DECLARE
int NUMBER ( 2 ): = 0 ;
BEGIN
LOOP
int : = int + 1 ;
DBMS_OUTPUT.PUT_LINE(
' int的当前值为: ' || int );
EXIT WHEN int = 10 ;
END LOOP;
END ;

2.WHILE循环

WHILE < 布尔表达式 > LOOP
要执行的语句;
END LOOP;

7.

DECLARE
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。跟在INREVERSE后面的数字必须是从小到大的顺序,而且必须是整数,不能是变量或表达式。可以使用EXIT退出循环。

8.

BEGIN
FOR int in 1 .. 10 LOOP
DBMS_OUTPUT.PUT_LINE(
' int的当前值为: ' || int );
END LOOP;
END ;

9.

CREATE 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:

DECLARE
TYPEjobids_varray
IS VARRAY( 12 ) OF VARCHAR2 ( 10 ); -- 定义一个VARRAY数据类型
v_jobidsJOBIDS_VARRAY; -- 声明一个具有JOBIDS_VARRAY数据类型的变量
v_howmany NUMBER ; -- 声明一个变量来保存雇员的数量

BEGIN
-- 用某些job_id值初始化数组
v_jobids: = jobids_varray( ' FI_ACCOUNT ' , ' FI_MGR ' , ' ST_CLERK ' , ' ST_MAN ' );

-- 用FOR...LOOP...ENDLOOP循环使用每个数组成员的值
FOR i IN v_jobids.FIRST..v_jobids.LASTLOOP

-- 针对数组中的每个岗位,决定该岗位的雇员的数量
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 ;

11While循环中嵌套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 ;

3.4标号和GOTO

PL/SQLGOTO语句是无条件跳转到指定的标号去的意思。语法如下:

GOTO label;
......
<< label >>   /* 标号是用<< >>括起来的标识符 */

注意,在以下地方使用是不合法的,编译时会出错误。

u跳转到非执行语句前面。

u跳转到子块中。

u跳转到循环语句中。

u跳转到条件语句中。

u从异常处理部分跳转到执行。

u从条件语句的一部分跳转到另一部分。

12:

DECLARE
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 ;

3.5NULL语句

PL/SQL程序中,NULL语句是一个可执行语句,可以用null语句来说明不用做任何事情的意思,相当于一个占位符或不执行任何操作的空语句,可以使某些语句变得有意义,提高程序的可读性,保证其他语句结构的完整性和正确性。如:

14:

DECLARE
...
BEGIN
...
IF v_num IS NULL THEN
GOTO labelPrint;
END IF ;

<< labelPrint >>
NULL ; -- 不需要处理任何数据。
END ;

15:

DECLARE
v_emp_idemployees.employee_id
% TYPE;
v_first_nameemployees.first_name
% TYPE;
v_salaryemployees.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 ;

©2011EricHu

原创作品,转贴请注明作者和出处,留此信息。

------------------------------------------------

cnBlobs:http://www.cnblogs.com/huyong/
优快云http://blog.youkuaiyun.com/chinahuyong

作者:EricHuDBC/SB/SWebServiceWCFPM
出处:http://www.cnblogs.com/huyong/

QQ80368704E-Mail:80368704@qq.com
本博文欢迎大家浏览和转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,在『参考』的文章中,我会表明参考的文章来源,尊重他人版权。若您发现我侵犯了您的版权,请及时与我联系。
更多文章请看[置顶]索引贴——(不断更新中)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值