plsql 文章

SQL实例分析

第五章

1、PL/SQL实例分析

1)在【SQLPlusWorksheet】中直接执行如下SQL代码完成上述操作。(创建表)

―――――――――――――――――――――――――――――――

CREATETABLE"SCOTT"."TESTTABLE"("RECORDNUMBER"NUMBER(4)NOTNULL,"CURRENTDATE"DATENOTNULL)

TABLESPACE"SYSTEM"

2)以admin用户身份登录【SQLPlusWorksheet】,执行下列SQL代码完成向数据表SYSTEM.testable中输入100个记录的功能。

―――――――――――――――――――――――――――――――

setserveroutputon

declare

maxrecordsconstantint:=100;--constant是常量的

iint:=1;

begin

foriin1..maxrecordsloop

insertintoSCOTT.testtable(recordnumber,currentdate)

values(i,sysdate);

endloop;

dbms_output.put_line('成功录入数据!');

commit;

end;

2、在【SQLPlusWorksheet】中执行下列PL/SQL程序,该程序定义了名为age的数字型变量,长度为3,初始值为26。

―――――――――――――――――――――――――――――――

declare

agenumber(3):=26;

begin

commit;

end;

3、在【SQLPlusWorksheet】中执行下列PL/SQL程序,该程序定义了名为pi的数字型常量,长度为9。

―――――――――――――――――――――――――――――――

declare

piconstantnumber(9):=3.1415926;

begin

commit;

end;

4、复合数据类型变量

下面介绍常见的几种复合数据类型变量的定义。

1).使用%type定义变量

为了让PL/SQL中变量的类型和数据表中的字段的数据类型一致,Oracle9i提供了%type定义方法。这样当数据表的字段类型修改后,PL/SQL程序中相应变量的类型也自动修改。

在【SQLPlusWorksheet】中执行下列PL/SQL程序,该程序定义了名为mydate的变量,其类型和tempuser.testtable数据表中的currentdate字段类型是一致的。

―――――――――――――――――――――――――――――――

Declare

mydateSYSTEM.testtable.currentdate%type;

begin

commit;

end;

2).定义记录类型变量

很多结构化程序设计语言都提供了记录类型的数据类型,在PL/SQL中,也支持将多个基本数据类型捆绑在一起的记录数据类型。

下面的程序代码定义了名为myrecord的记录类型,该记录类型由整数型的myrecordnumber和日期型的mycurrentdate基本类型变量组成,srecord是该类型的变量,引用记录型变量的方法是“记录变量名.基本类型变量名”。

程序的执行部分从tempuser.testtable数据表中提取recordnumber字段为68的记录的内容,存放在srecord复合变量里,然后输出srecord.mycurrentdate的值,实际上就是数据表中相应记录的currentdate的值。

在【SQLPlusWorksheet】中执行下列PL/SQL程序

―――――――――――――――――――――――――――――――

setserveroutputon

declare

typemyrecordisrecord(myrecordnumberint,mycurrentdatedate);

srecordmyrecord;

begin

select*intosrecordfromSYSTEM.testtablewhererecordnumber=68;

dbms_output.put_line(srecord.mycurrentdate);

end;

3).使用%rowtype定义变量

使用%type可以使变量获得字段的数据类型,使用%rowtype可以使变量获得整个记录的数据类型。比较两者定义的不同:变量名数据表.列名%type,变量名数据表%rowtype。

在【SQLPlusWorksheet】中执行下列PL/SQL程序,该程序定义了名为mytable的复合类型变量,与testtable数据表结构相同.

―――――――――――――――――――――――――――――――

Declare

mytableSYSTEM.testtable%rowtype;

begin

select*intomytablefromSYSTEM.testtablewhererecordnumber=89;

dbms_output.put_line(mytable.currentdate);

end;

4).定义一维表类型变量

表类型变量和数据表是有区别的,定义表类型变量的语法如下:

―――――――――――――――――――――――――――――――

type表类型istableof类型indexbybinary_integer;

表变量名表类型;

―――――――――――――――――――――――――――――――

类型可以是前面的类型定义,indexbybinary_integer子句代表以符号整数为索引,这样访问表类型变量中的数据方法就是“表变量名(索引符号整数)”。

在【SQLPlusWorksheet】中执行下列PL/SQL程序,该程序定义了名为tabletype1和tabletype2的两个一维表类型,相当于一维数组。table1和table2分别是两种表类型变量。

―――――――――――――――――――――――――――――――

Declare

typetabletype1istableofvarchar2(4)indexbybinary_integer;

typetabletype2istableofSYSTEM.testtable.recordnumber%typeindexbybinary_integer;

table1tabletype1;

table2tabletype2;

begin

table1(1):='大学';

table1(2):='大专';

table2(1):=88;

table2(2):=55;

dbms_output.put_line(table1(1)||table2(1));

dbms_output.put_line(table1(2)||table2(2));

end;

执行结果如下所示。

―――――――――――――――――――――――――――――――

大学88

大专55

PL/SQL过程已成功完成。

二、表达式

在PL/SQL中常见表达式的运算规则:

1.数值表达式

PL/SQL程序中的数值表达式是由数值型常数、变量、函数和算术运算符组成的,可以使用的算术运算符包括+(加法)、-(减法)、*(乘法)、/(除法)和**(乘方)等。

在【SQLPlusWorksheet】中执行下列PL/SQL程序,该程序定义了名为result的整数型变量,

计算的是10+3*4-20+5**2的值。

注意:dbms_output.put_line函数输出只能是字符串,因此利用to_char函数将数值型结果转换为字符型。

―――――――――――――――――――――――――――――――

setserveroutputon

Declare

resultinteger;

begin

result:=10+3*4-20+5**2;

dbms_output.put_line('运算结果是:'||to_char(result));

end;

―――――――――――――――――――――――――――――――

执行结果如下所示。

运算结果是:27

PL/SQL过程已成功完成。

三、流程控制

PL/SQL程序中的流程控制语句借鉴了许多高级语言的流程控制思想,但又有自己的特点。

(一)条件控制

1.if..then..endif条件控制

采用if..then..endif条件控制的语法结构如:

if条件then

语句段;

endif;

if..then..endif条件控制语法结构

在【SQLPlusWorksheet】中执行下列PL/SQL程序,该程序判断两个整数变量的大小。

―――――――――――――――――――――――――――――――

setserveroutputon

declare

number1integer:=90;

number2integer:=60;

begin

ifnumber1>=number2then

dbms_output.put_line('number1大于等于number2');

endif;

end;

―――――――――――――――――――――――――――――――

执行结果:

number1大于等于number2

PL/SQL过程已成功完成。

2.if..then..else..endif条件控制

采用if..then..else..endif条件控制的语法结构:

if条件then

语句段1;

else

语句段2;

endif;

在【SQLPlusWorksheet】中执行下列PL/SQL程序,该程序判断输出不同的结果。

―――――――――――――――――――――――――――――――

setserveroutputon

declare

number1integer:=80;

number2integer:=90;

begin

ifnumber1>=number2then

dbms_output.put_line('number1大于等于number2');

else

dbms_output.put_line('number1小于number2');

endif;

end;

―――――――――――――――――――――――――――――――

执行结果:

number1大于等于number2

PL/SQL过程已成功完成。

3.if嵌套条件控制

采用if嵌套条件控制的语法结构如:

if条件1then

if条件2then

嵌套的条件控制语句

语句段1;

else

语句段2;

endif;

else

语句段3;

endif;

在【SQLPlusWorksheet】中执行下列PL/SQL程序,该程序判断两个整数变量的大小,输出不同的结果。

―――――――――――――――――――――――――――――――

setserveroutputon

declare

number1integer:=110;

number2integer:=90;

begin

ifnumber1<=number2then

ifnumber1=number2then

dbms_output.put_line('number1等于number2');

else

dbms_output.put_line('number1小于number2');

endif;

else

dbms_output.put_line('number1大于number2');

endif;

end;

―――――――――――――――――――――――――――――――执行结果:?

(二)循环控制

循环结构是按照一定逻辑条件执行一组命令,PL/SQL中有4种基本循环结构:

1.loop..exit..endloop循环控制

采用loop..exit..endloop循环控制的语法结构如下所示:

loop

循环语句段;

if条件语句then

exit;

else

退出循环的处理语句段;

endif;

endloop;

在【SQLPlusWorksheet】中执行下列PL/SQL程序,该程序将number1变量每次加1,一直到等于number2为止,统计输出循环次数。

―――――――――――――――――――――――――――――――

setserveroutputon

declare

number1integer:=80;

number2integer:=90;

iinteger:=0;

begin

loop

number1:=number1+1;

ifnumber1=number2then

exit;

else

i:=i+1;

endif;

endloop;

dbms_output.put_line('共循环次数:'||to_char(i));

end;

―――――――――――――――――――――――――――――――

执行结果:?

习题:已知执行结果如下:

―――――――――――――――――――――――――――――――

变量number1为:101

变量number1为:102

变量number1为:103

变量number1为:104

变量number1为:105

变量number1为:106

变量number1为:107

共循环次数:7

PL/SQL过程已成功完成。

―――――――――――――――――――――――――――――――如何修改PL/SQL程序:?

setserveroutputon

declare

number1integer:=100;

number2integer:=108;

iinteger:=0;

begin

loop

number1:=number1+1;

ifnumber1=number2then

exit;

else

dbms_output.put_line('变量number1为:'||to_char(number1));

i:=i+1;

endif;

endloop;

dbms_output.put_line('共循环次数:'||to_char(i));

end;

―――――――――――――――――――――――――――――――

2.loop..exit..when..endloop循环控制

采用loop..exit..when..endloop循环控制的语法结构与上例结构类似。

exitwhen实际上就相当于

if条件then

exit;

endif;

在【SQLPlusWorksheet】中执行下列PL/SQL程序,该程序将number1变量每次加1,直到等于number2为止,统计输出循环次数。

―――――――――――――――――――――――――――――――

setserveroutputon

declare

number1integer:=80;

number2integer:=90;

iinteger:=0;

begin

loop

number1:=number1+1;

i:=i+1;

exitwhennumber1=number2;

endloop;

dbms_output.put_line('共循环次数:'||to_char(i));

end;

―――――――――――――――――――――――――――――――

执行结果?

3.while..loop..endloop循环控制

采用loop..exit..when..endloop循环控制的语法如下:

while条件loop

执行语句段;

endloop;

在【SQLPlusWorksheet】中执行下列PL/SQL程序,该程序将number1变量每次加1,一直到等于number2为止,统计输出循环次数。

―――――――――――――――――――――――――――――――――――――

setserveroutputon

declare

number1integer:=80;

number2integer:=90;

iinteger:=0;

begin

whilenumber1<number2loop

number1:=number1+1;

i:=i+1;

endloop;

dbms_output.put_line('共循环次数:'||to_char(i));

end;

―――――――――――――――――――――――――――――――――――――

4.for..in..loop..end循环控制

采用for..in..loop..end循环控制的语法如下:

for循环变量in[reverse]循环下界..循环上界loop

循环处理语句段;

endloop;

在【SQLPlusWorksheet】中执行下列PL/SQL程序,该程序通过循环变量I来控制number1增加次数,输出结果。

―――――――――――――――――――――――――――――――――――――

setserveroutputon

declare

number1integer:=80;

number2integer:=90;

iinteger:=0;

begin

foriin1..10loop

number1:=number1+1;

endloop;

dbms_output.put_line('number1的值:'||to_char(number1));

end;

―――――――――――――――――――――――――――――――――――――

执行结果?

用SQL进行函数查询

Oracle9i提供了很多函数可以用来辅助数据查询。接下来我们介绍常用的函数功能及使

用方法。

5.5.1【ceil】函数

【ceil】函数用法:ceil(n),取大于等于数值n的最小整数。

在【命令编辑区】输入“selectmgr,mgr/100,ceil(mgr/100)fromscott.emp;”,然后单击【执

行】按钮,出现结果?

5.5.2【floor】函数

【floor】函数用法:floor(n),取小于等于数值n的最大整数。

在【命令编辑区】输入“selectmgr,mgr/100,floor(mgr/100)fromscott.emp;”,然后单击【执

行】按钮,出现结果?

5.5.3【mod】函数

【mod】函数用法:mod(m,n),取m整除n后的余数。

在【命令编辑区】输入“selectmgr,mod(mgr,1000),mod(mgr,100),mod(mgr,10)

fromscott.emp;”,然后单击【执行】按钮,出现结果?

5.5.4【power】函数

【power】函数用法:power(m,n),取m的n次方。

在【命令编辑区】输入“selectmgr,power(mgr,2),power(mgr,3)fromscott.emp;”,然后单

击【执行】按钮,出现结果?

5.5.5【round】函数

【round】函数用法:round(m,n),四舍五入,保留n位。在【命令编辑区】输入“selectmgr,round(mgr/100,2),round(mgr/1000,2)fromscott.emp;”,

然后单击【执行】按钮,出现结果?

5.5.6【sign】函数

【sign】函数用法:sign(n)。n>0,取1;n=0,取0;n<0,取-1。

在【命令编辑区】输入“selectmgr,mgr-7800,sign(mgr-7800)fromscott.emp;”,然后单击

【执行】按钮,出现结果?

5.5.7【avg】函数

【avg】函数用法:avg(字段名),求平均值。要求字段为数值型。

在【命令编辑区】输入“selectavg(mgr)平均薪水fromscott.emp;”,然后单击【执行】

按钮,出现结果?

5.5.8【count】函数

(1)在【命令编辑区】输入“selectcount(*)记录总数fromscott.emp;”,然后单击【执

行】按钮,出现结果?

【count(*)】函数的使用

(2)在【命令编辑区】输入“selectcount(distinctjob)工作类别总数fromscott.emp;”,

然后单击【执行】按钮,出现结果?

【count(字段名)】函数的使用

【count】函数用法:count(字段名)或count(*),统计总数。

5.5.9【min】函数

在【命令编辑区】输入“selectmin(sal)最少薪水fromscott.emp;”,然后单击【执行】

按钮,出现结果?

【min】函数用法:min(字段名),计算数值型字段最小数。

5.5.10【max】函数

在【命令编辑区】输入“selectmax(sal)最高薪水fromscott.emp;”,然后单击【执行】

按钮,出现结果?

图4.39【max】函数的使用

【max】函数用法:max(字段名),计算数值型字段最大数。

5.5.11【sum】函数

在【命令编辑区】输入“selectsum(sal)薪水总和fromscott.emp;”,然后单击【执行】

按钮,出现结果?

【sum】函数用法:sum(字段名),计算数值型字段总和。

5.7游标

游标是从数据表中提取出来的数据,以临时表的形式存放在内存中,在游标中有一个数

据指针,在初始状态下指向的是首记录,利用fetch语句可以移动该指针,从而对游标中的数

据进行各种操作,然后将操作结果写回数据表中。

1定义游标

游标作为一种数据类型,首先必须进行定义,其语法如下。

cursor游标名isselect语句;

cursor是定义游标的关键词,select是建立游标的数据表查询命令。

以scott用户连接数据库,在【SQLPlusWorksheet】中执行下列PL/SQL程序,该程序定

义tempsal为与scott.emps数据表中的sal字段类型相同的变量,mycursor为从scott.emp数据

表中提取的sal大于tempsal的数据构成的游标。

―――――――――――――――――――――――――――――――――――――

setserveroutputon

declare

tempsalscott.emp.sal%type;

cursormycursoris

select*fromscott.emp

wheresal>tempsal;

begin

tempsal:=800;

openmycursor;

end;

―――――――――――――――――――――――――――――――――――――

执行结果?

2打开游标

要使用创建好的游标,接下来要打开游标,语法结构如下:

open游标名;

打开游标的过程有以下两个步骤:

(1)将符合条件的记录送入内存。

(2)将指针指向第一条记录。

3提取游标数据

要提取游标中的数据,使用fetch命令,语法形式如下。

fetch游标名into变量名1,变量名2,……;

或fetch游标名into记录型变量名;

在【SQLPlusWorksheet】中执行下列PL/SQL程序,该程序定义cursorrecord变量是游

标mycursor的记录行变量,在游标mycursor的结果中找到sal字段大于800的第一个记录,

显示deptno字段的内容。

提取游标数据

―――――――――――――――――――――――――――――――――――――

setserveroutputon

declare

tempsalscott.emp.sal%type;

cursormycursoris

select*fromscott.emp

wheresal>tempsal;

cursorrecordmycursor%rowtype;

begin

tempsal:=3000;

Openmycursor;

fetchmycursorintocursorrecord;

dbms_output.put_line(to_char('NAME:'||cursorrecord.ENAME||',deptno:'||cursorrecord.deptno));

end;

―――――――――――――――――――――――――――――――――――――

执行结果?

NAME:KING,deptno:10

4关闭游标

使用完游标后,要关闭游标,使用close命令,语法形式如下:

close游标名;

5游标的属性

游标提供的一些属性可以帮助编写PL/SQL程序,游标属性的使用方法为:游标名[属性],

例如mycursor%isopen,主要的游标属性如下。

1.%isopen属性

该属性功能是测试游标是否打开,如果没有打开游标就使用fetch语句将提示错误。

在【SQLPlusWorksheet】中执行下列PL/SQL程序,该程序利用%isopen属性判断游标

是否打开。执行结果?

―――――――――――――――――――――――――――――――――――――

setserveroutputon

declare

tempsalscott.emp.sal%type;

cursormycursoris

select*fromscott.emp

wheresal>tempsal;

cursorrecordmycursor%rowtype;

begin

tempsal:=800;

ifmycursor%isopenthen

fetchmycursorintocursorrecord;

dbms_output.put_line(to_char(cursorrecord.deptno));

else

dbms_output.put_line('游标没有打开!');

endif;

end;

―――――――――――――――――――――――――――――――――――――

游标没有打开!

2.%found属性

该属性功能是测试前一个fetch语句是否有值,有值将返回true,否则为false。

在【SQLPlusWorksheet】中执行下列PL/SQL程序。该程序利用%found属性判断游标是

否有数据。

执行结果?

―――――――――――――――――――――――――――――――――――――

setserveroutputon

declare

tempsalscott.emp.sal%type;

cursormycursoris

select*fromscott.emp

wheresal>tempsal;

cursorrecordmycursor%rowtype;

begin

tempsal:=800;

openmycursor;

fetchmycursorintocursorrecord;

ifmycursor%foundthen

dbms_output.put_line(to_char(cursorrecord.deptno));

else

dbms_output.put_line('没有数据!');

endif;

end;

―――――――――――――――――――――――――――――――――――――

30

3.%notfound属性

该属性是%found属性的反逻辑,常被用于退出循环。

在【SQLPlusWorksheet】中执行下列PL/SQL程序。该程序利用%notfound属性判断游

标是否没有数据。

执行结果?

发现数据!

―――――――――――――――――――――――――――――――――――――

setserveroutputon

declare

tempsalscott.emp.sal%type;

cursormycursoris

select*fromscott.emp

wheresal>tempsal;

cursorrecordmycursor%rowtype;

begin

tempsal:=800;

openmycursor;

fetchmycursorintocursorrecord;

ifmycursor%notfoundthen

dbms_output.put_line(to_char(cursorrecord.deptno));

else

dbms_output.put_line('发现数据!');

endif;

end;

―――――――――――――――――――――――――――――――――――――

4.%rowcount属性

该属性用于返回游标的数据行数。

在SQLPlusWorksheet的【代码编辑区】执行下列PL/SQL程序,该程序利用%rowcount

属性判断游标数据行数。

执行结果?

―――――――――――――――――――――――――――――――――――――

Setserveroutputon

declare

tempsalscott.emp.sal%type;

cursormycursoris

select*fromscott.emp

wheresal>tempsal;

cursorrecordmycursor%rowtype;

begin

tempsal:=800;

openmycursor;

fetchmycursorintocursorrecord;

dbms_output.put_line(to_char(mycursor%rowcount));

end;

―――――――――――――――――――――――――――――――――――――

1

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/aicon/archive/2010/04/21/5511454.aspx

相关推荐