Oracle程序开发范例宝典
上QQ阅读APP看书,第一时间看更新

第4章 PL/SQL流程控制

数据类型的使用

流程控制语句

实例097 计算两个整数的和与这个两个整数的差的商

这是一个可以提高基础技能的实例

实例位置:光盘\mingrisoft\04\097

实例说明

PL/SQL(Procedural Language/SQL)是一种过程化语言,在PL/SQL 中可以通过IF 语句或LOOP 语句实现控制程序的执行流程,甚至可以定义变量,以便在语句之间传递数据信息,这样PL/SQL语言就能够实现操控程序处理的细节过程,不像普通的SQL语句(如DML语句、DQL语句)那样没有流程控制,也不存在变量,因此使用PL/SQL语言可以实现比较复杂的业务逻辑。PL/SQL是Oracle的专用语言,它是对标准SQL语言的扩展,它允许在其内部嵌套普通的SQL语句,这样就将SQL语句的数据操纵能力、数据查询能力和PL/SQL的过程处理能力结合在一起,到达各自取长补短的目的。

接下来通过本实例来看一下PL/SQL块的完整应用。定义一个PL/SQL代码块,计算两个整数的和与这个两个整数的差的商,本例运行结果如图4.1所示。

图4.1 求两个整数的和与差的商

技术要点

PL/SQL程序都是以块(BLOCK)为基本单位,整个PL/SQL块分三部分:声明部分(用DECLARE开头)、执行部分(以BEGIN开头)和异常处理部分(以EXCEPTION开头)。其中执行部分是必须的,其他两个部分可选。无论PL/SQL程序段的代码量有多大,其基本结构就是由这三部分组成。标准PL/SQL块的语法格式如下:

[DECLARE]

--声明部分,可选

BEGIN

--执行部分,必须

[EXCEPTION]

--异常处理部分,可选

END

接下来对PL/SQL块的3个组成部分进行详细说明。

(1)声明部分由关键字DECLARE开始,到BEGIN关键字结束。在这部分可以声明PL/SQL程序块中所用到的变量、常量和游标等。需要注意的是,在某个PL/SQL块中声明的内容只能在当前块中使用,而在其他PL/SQL块中是无法引用的。

(2)执行部分以关键字BEGIN开始,它的结束方式通常有两种。如果PL/SQL块中的代码在运行时出现异常,则执行完异常处理部分的代码就结束;如果没有使用异常处理或的PL/SQL块未出现异常,则以关键字END结束。执行部分是整个PL/SQL程序块的主体,主要的逻辑控制和运算都在这部分完成,所以在执行部分可以包含多个PL/SQL语句和SQL语句。

(3)异常处理部分以关键字EXCEPTION开始,在该关键字所包含的代码执行完毕,整个PL/SQL块也就结束了。在执行PL/SQL代码(主要是执行部分)的过程中,可能会产生一些意向不到的错误,如除数为零、空值参与运算等,这些错误都会导致程序中断运行。这样程序设计人员就可以在异常处理部分通过编写一定量的代码来纠正错误或者给用于提供一些错误信息提示,甚至是将各种数据操作回退到异常产生之前的状态,以备重新运行代码块。另外,对于可能出现的多种异常情况,用户可以使用WHEN…THEN语句来实现多分支判断,然后就可以在每个分支下通过编写代码来处理相应的异常。

对于PL/SQL块中的语句,需要指出的是,每一条语句都必须以分号结束,每条SQL语句可以写成多行的形式,同样必须使用分号来结束。另外,一行中也可以有多条SQL语句,但是它们之间必须以分号分隔。

实现过程

(1)启动SQL*Plus,输入用户名scott、口令tiger连接数据库。

(2)定义一个PL/SQL代码块,计算两个整数的和与这个两个整数的差的商。

(3)主要程序代码如下:

SQL> set serveroutput on

SQL> declare

a int:=100;

b int:=200;

c number;

begin

c:=(a+b)/(a-b);

dbms_output.put_line(c);

exception

when zero_divide then

dbms_output.put_line('除数不许为零!');

end;

/

在上面的代码中,首先使用“set serveroutput on”命令来实现在服务端显示执行结果,然后使用declare关键字声明3个变量,其中,前两个整型(int)变量a和b的初始值分别为100和 200,最后在 PL/SQL 块的执行部分计算出这个两个整数的和与它们之间差的商,并调用“dbms_output.put_line(c);”语句输出计算结果。另外,为了防止除数为零的情况发生,代码中还设置了异常处理部分。若发生除数为零的情况,则代码块通过调用“dbms_output.put_line('除数不许为零!');”语句向用户输出提示信息。

举一反三

根据本实例,读者可以进行以下操作。

求三个整数的和与差的商。

实例098 添加单行注释

这是一个可以提高基础技能的实例

实例位置:光盘\mingrisoft\04\098

实例说明

注释用于对程序代码的解释说明,它能够增强程序的可读性,使程序更易于理解。注释编译时被PL/SQL编译器忽略掉,注释有单行注释和多行注释两种情况。本实例编写一段PL/SQL代码块,并为主要代码添加单行注释。

技术要点

单行注释由两个连接字符“--”开始,后面紧跟着注释内容。

实现过程

(1)启动SQL*Plus,输入用户名scott、口令tiger连接数据库。

(2)使用“--”为代码添加单行注释。

(3)主要程序代码如下:

SQL> set serveroutpu on           --在服务器端输出结果

SQL> declare

Num_sal number;           --声明一个数值变量

Var_ename varchar2(20);         --声明一个字符串变量

begin

select ename,sal into Var_ename,Num_sal from emp --检索指定的值并存储到变量中

where empno=7369;

dbms_output.put_line(Var_ename||'的工资是'||Num_sal);--输出变量中值

end;

举一反三

根据本实例,读者可以进行以下操作。

给实例097添加单行注释。

实例099 添加多行注释

这是一个可以提高基础技能的实例

实例位置:光盘\mingrisoft\04\099

实例说明

本实例编写一段PL/SQL代码块,并为主要代码添加多行注释。

技术要点

多行注释由/*开头,由*/结尾,这个大多数编程语言是相同的。

实现过程

(1)启动SQL*Plus,输入用户名scott、口令tiger连接数据库。

(2)使用“/*”“*/”为代码添加多行注释。

(3)主要程序代码如下:

SQL> set serveroutpu on              /*在服务器端输出结果*/

SQL> declare

Num_sal number;              /*声明一个数值变量*/

Var_ename varchar2(20);           /*声明一个字符串变量*/

begin

/*检索指定的值并存储到变量中*/

select ename,sal into Var_ename,Num_sal from emp

where empno=7369;.

/*输出变量中值*/

dbms_output.put_line(Var_ename||'的工资是'||Num_sal);

end;

/

举一反三

根据本实例,读者可以进行以下操作。

给实例097添加多行注释。

实例100 使用%type类型的变量输出emp表中编号为7369的员工名称和职务

这是一个可以提高基础技能的实例

实例位置:光盘\mingrisoft\04\100

实例说明

为了提高用户的编程效率和解决复杂的业务逻辑需求,PL/SQL 语言除了可以使用 Oracle规定的基本数据类型外,还提供了 3 种特殊的数据类型,分别为%TYPE类型、RECORD类型、%ROWTYPE类型。本实例主要讲解了%TYPE类型的变量。在scott模式下,使用%type类型的变量输出emp表中编号为7369的员工名称和职务信息。本例运行结果如图4.2所示。

图4.2 使用%type类型定义变量并输出

技术要点

使用%TYPE 关键字可以声明一个与指定列名称相同的数据类型,它通常紧跟在指定列名的后面。

例如,声明一个与emp表中job列的数据类型完全相同的变量var_job,代码如下:

declare

var_job emp.job%type;

在上面的代码中,若emp.job列的数据类型为VARCHAR2(10),那么变量var_job的数据类型也是VARCHAR2(10),甚至可以把“emp.job%type”就看做是一种能够存储指定列类型的特殊数据类型。

使用%TYPE 定义变量有两个好处:第一,用户不必查看表中各个列的数据类型,就可以确保所定义的变量能够存储检索的数据;第二:如果对表中已有列的数据类型进行修改,则用户不必考虑对已定义的变量所使用的数据类型进行更改,因为%TYPE 类型的变量会根据列的实际类型自动调整自身的数据类型。

实现过程

(1)启动SQL*Plus,输入用户名scott、口令tiger连接数据库。

(2)使用%type类型的变量。

(3)主要程序代码如下:

SQL> set serveroutput on

SQL> declare

var_ename emp.ename%type;         --声明与ename列类型相同的变量

var_job emp.job%type;          --声明与job列类型相同的变量

begin

select ename,job

into var_ename,var_job

from emp

where empno=7369;           --检索数据,并保存在变量中

dbms_output.put_line(var_ename||'的职务是'||var_job); --输出变量的值

end;

/

另外,在上面代码中使用into子句,它位于select子句的后面,用于表示将从数据库检索的数据存储到哪个变量中。

注意:由于into子句中的变量只能存储一个单独的值,所以要求select子句只能返回一行数据,这个由where子句进行了限定。若SELECT子句返回多行数据,则代码运行后会返回错误信息。

举一反三

根据本实例,读者可以进行以下操作。

使用%type类型的变量输出emp表中编号为7369的工资和部门号

实例101 声明%ROWTYPE 类型的变量rowVar_emp

这是一个可以提高基础技能的实例

实例位置:光盘\mingrisoft\04\101

实例说明

本实例讲解了如何定义和使用%ROWTYPE类型。声明一个%ROWTYPE 类型的变量 rowVar_emp,然后使用该变量存储emp表中的一行数据。本例运行结果如图4.3所示。

图4.3 定义和使用%ROWTYPE类型

技术要点

%ROWTYPE类型的变量结合了“%TYPE类型”和“记录类型”变量的优点,它可以根据数据表中行的结构定义一种特殊的数据类型,用来存储从数据表中检索到的一行数据。它的语法形式很简单,如下所示:

rowVar_name table_name%rowtype;

● rowVar_name:表示可以存储一行数据的变量名。

● table_name:指定的表名。

在上面的语法结构中,我们可以不恰当地把“table_name%rowtype”看做是一种能够存储表中一行数据的特殊类型。

实现过程

(1)启动SQL*Plus,输入用户名scott、口令tiger连接数据库。

(2)使用%ROWTYPE类型的变量。

(3)主要程序代码如下:

SQL> set serveroutput on

SQL> declare

rowVar_emp emp%rowtype;      --定义能够存储emp表中一行数据的变量rowVar_emp

begin

select *

into rowVar_emp

from emp

where empno=7369;         --检索数据

/*输出雇员信息*/

dbms_output.put_line('雇员'||rowVar_emp.ename||'的编号是'||rowVar_emp.empno||',职务是'||rowVar_emp.job);

end;

/

从上面的运行结果可以看出,变量rowVar_emp的存储结构与emp表的数据结构完全相同,这时用户完全可以使用rowVar_emp变量来代替emp表的某一行数据进行编程操作。

举一反三

根据本实例,读者可以进行以下操作。

声明一个记录类型emp_type,然后使用该类型的变量存储emp表中的一条记录信息,并输出这条记录信息。

实例102 声明记录类型emp_type存储一条记录信息

这是一个可以提高基础技能的实例

实例位置:光盘\mingrisoft\04\102

实例说明

单词 RECORD有“记录”之意,因此RECORD类型也称作“记录类型”,使用该类型的变量可以存储由多个列值组成的一行数据。声明一个记录类型emp_type,然后使用该类型的变量存储emp表中的一条记录信息,并输出这条记录信息。本例运行结果如图4.4所示。

图4.4 定义和使用记录类型

技术要点

在声明记录类型变量之前,首先需要定义记录类型,然后才可以声明记录类型的变量。记录类型是一种结构化的数据类型,它使用type语句进行定义,在记录类型的定义结构中包含成员变量及其数据类型,其语法格式如下:

type record_type is record

(

var_member1 data_type [not null] [:=default_value],

var_membern data_type [not null] [:=default_value])

● record_type:表示要定义的记录类型名称。

● var_member1:表示该记录类型的成员变量名称。

● data_type:表示成员变量的数据类型。

从上面的语法结构中可以看出,记录类型的声明类似于C或C++中的结构类型,并且成员变量的声明与普通PL/SQL变量的声明相同。

实现过程

(1)启动SQL*Plus,输入用户名scott、口令tiger连接数据库。

(2)使用RECORD记录数据。

(3)主要程序代码如下:

SQL> set serveroutput on

SQL> declare

type emp_type is record        --声明record类型emp_type

(

var_ename varchar2(20),       --定义字段/成员变量

var_job varchar2(20),

var_sal number

);

empinfo emp_type;        --定义变量

begin

select ename,job,sal

into empinfo

from emp

where empno=7369;         --检索数据

/*输出雇员信息*/

dbms_output.put_line('雇员'||empinfo.var_ename||'的职务是'||empinfo.var_job||'、工资是'||empinfo.var_sal);

end;

/

举一反三

根据本实例,读者可以进行以下操作。

声明一个记录类型dept_type,然后使用该类型的变量存储dept表中的一条记录信息,并输出这条记录信息。

实例103 定义变量和常量

这是一个可以提高基础技能的实例

实例位置:光盘\mingrisoft\04\102

实例说明

在上面的实例中,变量的定义和使用已经逐步的渗透给大家,相信读者对变量并不陌生,本实例主要是对定义变量的规范进行总结。另外,常量在PL/SQL编程中也经常用到,本实例也做相应的介绍。

技术要点

1.定义变量

变量是指其值在程序运行过程中可以改变的数据存储结构,定义变量必须的元素就是变量名和数据类型,另外还有可选择的初始值,其标准语法格式如下:

<变量名><数据类型> [(长度):=<初始值>];

可见,与很多面向对象的编程语言不同,PL/SQL 中的变量定义要求变量名在数据类型的前面,而不是后面;语法中的长度和初始值是可选项,需要根据实际情况而定。

2.定义常量

常量是指其值在程序运行过程中不可改变的数据存储结构,定义常量必须的元素包括常量名、数据类型、常量值和constant关键字,其标准语法格式如下:

<常量名> constant <数据类型>:=<常量值>;

对于一些固定的数值,如圆周率、光速等,为了防止不慎被改变,最好定义成变量。

实现过程

(1)定义一个用于存储国家名称的可变字符串变量var_countryname,该变量的最大长度是50,并且该变量的初始值为“中国”,代码如下:

var_countryname varchar2(50):='中国';

(2)定义一个常量con_day,用来存储一年的天数,代码如下:

con_day constant integer:=365;

举一反三

根据本实例,读者可以进行以下操作。

定义一个用于存储学生成绩的可变字符串变量 var_score,该变量的最大长度是 100,并且该变量的初始值为“0”。

定义一个常量con_pi,存储圆周率。

实例104 使用if…then语句比较两个字符串变量的长度

这是一个可以提高基础技能的实例

实例位置:光盘\mingrisoft\04\104

实例说明

选择语句也称之为条件语句,它的主要作用是根据条件的变化选择执行不同的代码,本实例用到的是if…then语句。定义两个字符串变量,然后赋值,接着使用if…then语句比较两个字符串变量的长度,并输出比较结果。本例运行结果如图4.5所示。

图4.5 使用if…then语句比较两个字符串长度

技术要点

本实例用到了if…then语句。

if...then语句是选择语句中最简单的一种形式,它只做一种情况或条件判断,其语法格式如下:

if < condition_expression> then

plsql_sentence

end if;

● condition_expression:表示一个条件表达式,当其值为 true 时,程序会执行 if 下面的PL/SQL 语句(即“plsql_sentence”语句);如果其值为 false,则程序会跳过 if 下面的语句而直接执行end if 后面的语句。

● plsql_sentence:当condition_expression 表达式的值为true 时,要执行的PL/SQL 语句。

实现过程

(1)启动SQL*Plus,输入用户名scott、口令tiger连接数据库。

(2)使用if...then语句比较两个字符串变量的长度。

(3)主要程序代码如下:

SQL> set serveroutput on

SQL> declare

var_name1 varchar2(50);       --定义两个字符串变量

var_name2 varchar2(50);

begin

var_name1:='East';         --给两个字符串变量赋值

var_name2:='xiaoke';

if length(var_name1) < length(var_name2) then --比较两个字符串的长度大小

/*输出比较后的结果*/

dbms_output.put_line('字符串“'||var_name1||'”的长度比字符串“'||var_name2||'”的长度小');

end if;

end;

/               --执行代码

在上面的例子中,字符串“East”的长度(4)肯定小于字符串“xiaoke”的长度(6),所以if后面的条件表达式的值为true,这样程序就会执行if下面的PL/SQL语句。

如果if后面的条件表达式存在“并且”、“或者”、“非”等逻辑运算,则可以使用“and”、“or”、“not”等逻辑运算符。另外,如果要判断 if 后面的条件表达式的值为空值,则需要在条件表达式中使用“is”和“null”关键字,比如下面的代码:

if last_name is null then

…;

end if;

举一反三

根据本实例,读者可以进行以下操作。

使用if...then比较两个数大小。

实例105 使用if…then…else语句判断退休年龄

这是一个可以提高基础技能的实例

实例位置:光盘\mingrisoft\04\105

实例说明

在编写程序的过程中,if...then...else 语句是最常用到的一种选择语句,它可以实现判断两种情况,只要if后面的条件表达式为false,程序就会执行else语句下面的PL/SQL语句。本实例通过if...then...else语句实现只有年龄大于等于56岁,才可以申请退休,否则程序会提示不可以申请退休。本例运行结果如图4.6所示。

图4.6 if...then...else语句判断退休年龄

技术要点

本实例用到了if...then...else语句,其语法格式如下:

if < condition_expression> then

plsql_sentence1;

else

plsql_sentence2;

end if;

● condition_expression:表示一个条件表达式,若该条件表达式的值为 true,则程序执行if下面的PL/SQL语句,即plsql_sentence1语句,否则程序将执行else下面的PL/SQL语句,即plsql_sentence2语句。

● plsql_sentence1:if 语句的表达式为true 时,要执行的PL/SQL 语句。

● plsql_sentence2:if 语句的表达式为false 时,要执行的PL/SQL 语句。

实现过程

(1)启动SQL*Plus,输入用户名scott、口令tiger连接数据库。

(2)使用if...then...else语句判断退休年龄。

(3)主要程序代码如下:

SQL> set serveroutput on

SQL> declare

age int:=55;

begin

if age >= 56 then

dbms_output.put_line('您可以申请退休了!');

else

dbms_output.put_line('您小于56岁,不可以申请退休了!');

end if;

end;

/

在上面的例子中,字符串“East”的长度(4)肯定小于字符串“xiaoke”的长度(6),所以if后面的条件表达式的值为true,这样程序就会执行if下面的PL/SQL语句。

如果if后面的条件表达式存在“并且”、“或者”、“非”等逻辑运算,则可以使用“and”、“or”、“not”等逻辑运算符。另外,如果要判断 if 后面的条件表达式的值为空值,则需要在条件表达式中使用“is”和“null”关键字,比如下面的代码:

if last_name is null then

…;

end if;

举一反三

根据本实例,读者可以进行以下操作。

使用if...then...else语句判断此人是否成年,年满18岁则可以考驾驶证。

实例106 使用if…then…elsif语句判断月份所属的季节

这是一个可以提高基础技能的实例

实例位置:光盘\mingrisoft\04\106

实例说明

指定一个月份数值,然后使用if...then...elsif语句判断它所属的季节,并输出季节信息。本例运行结果如图4.7所示。

图4.7 使用if...then...elsif语句判断季节

技术要点

if...then...elsif 语句实现了多分支判断选择,它使程序的判断选择条件更加丰富,更加多样化,该语句中的哪个判断分支的表达式为true,那么程序就会执行其下面对应的PL/SQL语句,其语法格式如下:

if < condition_expression1 > then

plsql_sentence_1;

elsif < condition_expression2 > then

plsql_sentence_2;

else

plsql_sentence_n;

end if;

● condition_expression1:第一个条件表达式,若其值为 false,则程序继续判断condition_expression2表达式。

● condition_expression2:第二个条件表达式,若其值false,则程序继续判断下面的elsif语句后面的表达式;若再没有“elsif”语句,则程序将执行 else 语句下面的 PL/SQL语句。

● plsql_sentence_1:第一个条件表达式的值为true 时,要执行的PL/SQL 语句。

● plsql_sentence_2:第二个条件表达式的值为true 时,要执行的PL/SQL 语句。

● plsql_sentence_n:当其上面所有的条件表达式的值都为 false 时,要执行的 PL/SQL语句。

注意:在 if...then...elsif 语句中,多个条件表达式之间不能存在逻辑上的冲突,否则程序将判断出错!

实现过程

(1)启动SQL*Plus,输入用户名scott、口令tiger连接数据库。

(2)使用if...then...elsif多条件选择语句,判断所属月份。

(3)主要程序代码如下:

SQL> set serveroutput on

SQL> declare

month int:=10;           --定义整形变量并赋值

begin

if month>=0 and month<=3 then    --判断春季

dbms_output.put_line('这是春季');

elsif month>=4 and month<=6 then   --判断夏季

dbms_output.put_line('这是夏季');

elsif month>=7 and month<=9 then   --判断秋季

dbms_output.put_line('这是秋季');

elsif month>=10 and month<=12 then   --判断冬季

dbms_output.put_line('这是冬季');

else

dbms_output.put_line('对不起,月份不合法!');

end if;

end;

/

举一反三

根据本实例,读者可以进行以下操作。

使用if...then...elsif语句判断员工所属的部门。

实例107 使用case语句判断指定季节所包含的月份信息

本实例可以提高工作效率

实例位置:光盘\mingrisoft\04\107

实例说明

指定一个季度数值,然后使用case语句判断它所包含的月份信息并输出。本例运行结果如图4.8所示。

图4.8 使用case判断某个季度所包含的月份

技术要点

从Oracle 9i 以后,PL/SQL 也可以像其他编程语言一样使用case 语句,case 语句的执行方式与if...then...elsif语句十分相似。在case关键字的后面有一个选择器,它通常是一个变量,程序就从这个选择器开始执行,接下来是when子句,并且在when关键字的后面是一个表达式,程序将根据选择器的值去匹配每个 when 子句中的表达式的值,从而实现执行不同的 PL/SQL语句,其语法格式如下:

case < selector>

when <expression_1> then plsql_sentence_1;

when <expression_2> then plsql_sentence_2;

when <expression_n> then plsql_sentence_n;

[else plsql_sentence;]

end case;

● selector:一个变量,用来存储要检测的值,通常称之为选择器。这选择器的值需要与when子句中的表达式的值进行匹配。

● expression_1:第一个when 子句中的表达式,这种表达式通常是一个常量,当选择器的值等于该表达式的值时,程序将执行plsql_sentence_1语句。

● expression_2:第二个when 子句中的表达式,它也通常是一个常量,当选择器的值等于该表达式的值时,程序将执行plsql_sentence_2语句。

● expression_n:第n 个when 子句中的表达式,它也通常是一个常量,当选择器的值等于该表达式的值时,程序将执行plsql_sentence_n语句。

● plsql_sentence:一个 PL/SQL 语句,当没有与选择器匹配的 when 常量时,程序将执行该PL/SQL语句,其所在的else语句是一个可选项。

技巧:在进行多种情况判断时,建议使用case替换if...then...elsif语句,因为case语句的语法更加简洁明了,易于阅读。

实现过程

(1)启动SQL*Plus,输入用户名scott、口令tiger连接数据库。

(2)使用case多重条件分支语句,判断所属月份。

(3)主要程序代码如下:

SQL> set serveroutput on

SQL> declare

season int:=3;               --定义整形变量并赋值

aboutInfo varchar2(50);            --存储月份信息

begin

case season                --判断季度

when 1 then               --若是1季度

aboutInfo := season||'季度包括1,2,3月份';

when 2 then               --若是2季度

aboutInfo := season||'季度包括4,5,6月份';

when 3 then               --若是3季度

aboutInfo := season||'季度包括7,8,9月份';

when 4 then               --若是4季度

aboutInfo := season||'季度包括10,11,12月份';

else                  --若季度不合法

aboutInfo := season||'季节不合法';

end case;

dbms_output.put_line(aboutinfo);         --输出该季度所包含的月份信息

end;

/

举一反三

根据本实例,读者可以进行以下操作。

使用case语句判断分数的优良中差。

实例108 使用loop/while语句求前100个自然数的和

本实例可以提高工作效率

实例位置:光盘\mingrisoft\04\108

实例说明

使用loop/while语句求前100个自然数的和,并输出到屏幕。

技术要点

loop 语句会先执行一次循环体,然后再判断“exit when”关键字后面的条件表达式的值是true还是false,如果是true,则程序会退出循环体,否则程序将再次执行循环体,这样就使得程序至少能够执行一次循环体,它的语法格式如下:

loop

plsql_sentence;

exit when end_condition_ exp

end loop;

● plsql_sentence:循环体中的PL/SQL 语句,可能是一条,也可能是多条,这是循环体的核心部分,这些PL/SQL语句至少被执行一遍。

● end_condition_ exp:循环结束条件表达式,当该表达式的值为true 时,则程序会退出循环体,否则程序将再次执行循环体。

while语句根据它的条件表达式的值执行零次或多次循环体,在每次执行循环体之前,首先要判断条件表达式的值是否为true,若为true,则程序执行循环体;否则退出while循环,然后继续执行while语句后面的其他代码,其语法格式如下:

while condition_expression loop

plsql_sentence;

end loop;

● condition_expression:表示一个条件表达式,但其值为 true 时,程序执行循环体,否则程序退出循环体,程序每次在执行循环体之前,都要首先判断该表达式的值是否为true。

● plsql_sentence:循环体内的PL/SQL 语句。

实现过程

(1)使用loop语句求前100个自然数的和,代码如下:

SQL> set serveroutput on

SQL> declare

sum_i int:=0;                  --定义整数变量,存储整数和

i int:=0;                   --定义整数变量,存储自然数

begin

loop                    --循环累加自然数

i:=i+1;                   --得出自然数

sum_i:= sum_i+i;                --计算前n个自然数的和

exit when i=100;                --当循环100次时,程序退出循环体

end loop;

dbms_output.put_line('前100个自然数的和是:'||sum_i);    --计算前100个自然数的和

end;

/

运行结果如图4.9所示。

图4.9 使用loop语句求得前100个自然数的和

(2)使用while语句求前100个自然数的和,代码如下:

SQL> set serveroutput on

SQL> declare

sum_i int:=0;                  --定义整数变量,存储整数和

i int:=0;                   --定义整数变量,存储自然数

begin

while i<=99 loop                 --当i的值等于100时,程序退出while循环

i:=i+1;                   --得出自然数

sum_i:= sum_i+i;                --计算前n个自然数的和

end loop;

dbms_output.put_line('前100个自然数的和是:'||sum_i);    --计算前100个自然数的和

end;

/

运行结果如图4.10所示。

图4.10 使用while语句求得前100个自然数的和

在上面的代码中,只要i的值小于100,程序就会反复地执行循环体,这样i的值就会自增1,从而得到一个新的自然数,然后使用sum_i这个变量存储前n个自然数的和,当i的值增长到100时,条件表达式的值就为false,导致while循环结束。

举一反三

根据本实例,读者可以进行以下操作。

使用loop/while语句求前200个自然数的偶数和。

实例109 使用for语句求前100个自然数中偶数之和

这是一个可以提高基础技能的实例

实例位置:光盘\mingrisoft\04\109

实例说明

使用for语句求前100个自然数中偶数之和,并输出到屏幕。本例运行结果如图4.11所示。

图4.11 使用for语句计算前100个自然数中偶数之和

技术要点

for语句是一个可预置循环次数的循环控制语句,它有一个循环计数器,通常是一个整型变量,通过这个循环计数器来控制循环执行的次数。该计数器可以从小到大进行记录,也可以相反,从大到小进行记录。另外,该计数器值的合法性由上限值和下限值控制,若计数器值在上限值和下限值的范围内,则程序执行循环;否则,终止循环,其语法格式如下:

for variable_ counter_name in [reverse] lower_limit..upper_limit loop

plsql_sentence;

end loop;

● variable_ counter_name::表示一个变量,通常为整数类型,用来作为计数器。默认情况下计数器的值会循环递增,当在循环中使用reverse关键字时,计数器的值会随循环递减。

● lower_limit:计数器的下限值,当计数器的值小于下限值时,程序终止for 循环。

● upper_limit:计数器的上限值,当计数器的值大于上限值时,程序终止for 循环。

● plsql_sentence:表示PL/SQL 语句,作为for 语句的循环体。

实现过程

主要程序代码如下:

SQL> set serveroutput on

SQL> declare

sum_i int:=0;         --定义整数变量,存储整数和

begin

for i in reverse1..100 loop     --遍历前100个自然数

if mod(i,2)=0 then       --判断是否为偶数

sum_i:=sum_i+i;      --计算偶数和

end if;

end loop;

dbms_output.put_line('前100个自然数中偶数之和是:'||sum_i);

end;

/

在上面的 for 语句中,由于使用了关键字“reverse”,表示计数器 i 的值为递减状态,即 i的初始值为100,随着每次递减1,最后一次for循环时i的值变为1。如果在for语句中不使用关键字reverse,则表示计数器i的值为递增状态,即i的初始值为1。

举一反三

根据本实例,读者可以进行以下操作。

使用for语句求前100个自然数中素数之和。

使用for语句求前100个自然数中奇数之和。