oracle数据库开发与应用 存储过程、函数和包 17

oracle数据库开发与应用 存储过程、函数和包 17

存储过程

存储过程的作用

image-20240524170550681

1
2
3
4
5
6
7
8
9
以上代码,可以将一些 SQL 操作集中起来。
但是,如果实现PL/SQL块代码重用时,就打开SQL脚本来手工运行,这样也太麻烦了。
因此,可以将一些需要反复使用的代码,指定一个名称,类似于其他编程语言中函数,调用时,用相应功能名称调用就可以了。

在oracle内,提供了两种常见的对象,供实现代码重用:
存储过程。将一些代码写在一个过程中,存储为数据库对象,供调用。过程没有返回值。
函数。将一些代码写在一个函数中,存储为数据库对象,供调用。函数有返回值。

当然,也可以用包将逻辑上相关的过程和函数组织在一起,便于对PL/SQL程序进行管理。

创建存储过程

1
2
3
4
5
6
7
存储过程用于执行某些操作,不返回任何值。其语法很简单,就是在标准PL/SQL程序块的基础上增加了一个程序头部,最简单的创建存储过程的语法如下:
CREATE OR REPLACE PROCEDURE 存储过程名称
AS(或者IS)
变量、常量定义;
BEGIN
代码;
END ;
1
此语法是最简单的创建存储过程的语法,更加复杂的语法将在后面讲解。

image-20240524170923923

调用存储过程

1
2
3
4
调用存储过程方法很简单,将存储过程的调用放在一个PL/SQL块中即可
BEGIN
存储过程名称(参数列表);
END;
1
2
3
4
5
6
当然,也可以放在另一个存储过程中嵌套调用

例:调用存储过程PRC_INSERT_STUNO,根据上面的语法,可以编写调用存储过程如下,
BEGIN
PRC_INSERT_STUNO;
END;
1
2
还有一种方法也可以调用存储过程。在PL/SQL Developer的命令窗口中,输入:
EXEC 存储过程名称;
1
2
3
当然,也可以使用下面语法删除存储过程
DROP PROCEDURE 存储过程名称;:
即可将存储过程删除

详解存储过程

带输入参数的存储过程

1
2
3
4
5
6
7
8
9
10
很明显,这是一个带参数的存储过程。在存储过程中,参数有两种:输入参数和输出参数。本存储过程中需要使用的是输入参数。给存储过程定义输入参数,只需要在存储过程名称的定义后面,加上参数定义即可。

CREATE OR REPLACE PROCEDURE
存储过程名称(参数1 类型1,参数2 类型2) AS(或者IS)
变量、常量定义;
BEGIN
代码;
END;

当然,也可以给参数以默认值。

image-20240524171523898

image-20240524171545449

存储过程内部的返回

1
2
在一个存储过程中,可能有非常复杂的逻辑,某些逻辑成立时,可能需要存储过程中剩下的代码中止运行。
存储过程内部的返回,是通过 RETURN 语句实现的。

image-20240525110649513

带输出参数的存储过程

1
2
3
存储过程之所以叫做“过程”,就是因为没有返回值。即使能够返回,也只能用RETURN语句,而不能用RETURN用某个值。例如,RETURN1在Oracle 中是错误的。有时候,又必须从存储过程中获取一些值,如下面的例子。

此时,可以编写带输出参数的存储过程。定义方法很简单,只需要在定义存储过程时,在某个参数的名称后面增加OUT关键字即可。
1
2
运行,即创建存储过程。
若要获取输出参数,只需要将某个变量传人存储过程,输出参数的内容就自动存人该变量。可以编写调用存储过程如下:

image-20240525111904302

1
实际上,在使用存储过程时,参数有3种引用模式IN、OUT和IN OUT。默认情况下是IN,OUT和INOUT参数必须在定义时被显式指定。IN OUT参数的使用较少。

函数

函数的作用

1
2
3
4
5
6
存储过程可以使用输出参数来得到一些“返回值”,但是,其使用起来有些复杂。另外,由于存储过程是一个可以独立调用PL/SQL语句,在某些特定场合,难以实现一些特定的功能。

例如,输入一个学生学号,如果该学生平均分在90分以上,则姓名按照姓在后、名在前的格式显示,并将该功能应用于对TSTUDENT表的查询中。该功能用存储过程很难实现。
函数可以简化这个功能。

与存储过程相比较,函数只能使用输入参数,可以通过专用的RETURN子句来返回计算值,而不能通过参数传出计算结果。函数也是Oracle数据库中的对象,定义方法和存储过程类似,但是功能和使用方法上有很多明显的区别,表17-1描述了存储过程和函数的区别。

image-20240525112216801

创建函数

1
2
3
4
5
6
7
8
9
函数被用来执行复杂的计算,并返回计算的结果。其语法很简单,就是在标准PL/SQL程序块的基础上增加了一个程序头部,最简单的创建函数的语法如下:
CREATE OR REPLACE FUNCTION
函数名称(参数1类型1,参数2类型2…)
RETURN 数据类型
AS(或者IS)
变量、常量定义;
BEGIN
代码;
END;

image-20240525112709184

1
2
3
输入参数定义和返回类型中的VARCHAR2,不要指定宽度。否则报错。例如,
RETURN VARCHAR2不能写成RETURN VARCHAR2(20)
RETURN(result)也可以写成RETURN result。

image-20240525113031305

1
当然,也可以放在另一个存储过程或者函数中嵌套调用。

image-20240525113239126

1
2
当然,也可以使用下面语法删除函数:
DROP FUNCTION 函数名称;

将函数使用到SQL语句

1
函数在数据库中最常见的作用是和SQL语句配合使用。在SQL语句中经常需要使用到表达式,函数在SQL语句中就作为表达式出现。

image-20240525113441988

1
2
3
4
5
在SQL语句中使用函数,有如下好处:
可以使SQL语句中出现那些用简单的方法不能实现的计算,例如,有些计算需要查询其他表中的数据,有些计算需要进行逻辑判断,这些计算在单个的SQL语句中难以实现,可以借助函数。

提高了SQL查询的效率。因为函数存储在数据库内部,减少了整个计算过程中的数据交互。
SQL语句中只能使用函数,而不能使用存储过程,

定义包

1
2
在大型项目中,希望程序能够有序组织、存储。包,提供了一个很好的工具。包,包括两个部分:包头和包体。在包头定义了包中可用的过程、函数、变量、常量的声明,在包体部分定义了包中的函数、过程的实际PL/SQL代码。
因此,定义包,包括两个步骤。

定义包头

1
2
3
4
5
6
CREATE OR REPLACE PACKAGE 包名
AS
变量、常量声明;
函数声明;
过程声明;
END ;
1
2
3
4
5
6
7
8
例:定义一个包PKG_SCHOOL,内含一个变量STUCOUNT,一个存储过程PRC_GETSTUCOUNT.
根据上面的语法,可以编写包的定义如下:

CREATE OR REPLACE PACKAGE PKG_SCHOOL
AS
stucount INT;
PROCEDURE PRC_GETSTUCOUNT
END;
1
运行,即创建包。在PL/SQL Developer 的树形目录中可以看到,如图17-14所示。
1
2
注意
此例中,包的定义中,有END,但是没有BEGIN,

定义包体

1
2
3
4
5
6
7
包体部分定义了包中的函数、过程的实际PL/SQL代码:定义包体的语法如下:
CREATE OR REPLACE PACKAGE BODY 包名
AS
BEGIN
函数实际代码;
过程实际代码;
END;

image-20240525114826771

1
2
3
注意
此例中,包体中的函数和过程的定义中,不能有CREATE OR REPLACE.
此例中,包体的定义中,最后有一个END,但是没有BEGIN和其匹配。

使用包

1
2
3
将存储过程或函数放入包中,只需要用“包名.过程/函数名”的方法即可调用包中的存储过程或者函数。

例:调用包PKG SCHOOL中的存储过程PRCGETSTUCOUNT

image-20240525115052465

image-20240525115118943