PL/SQL包是一组相关的过程,函数,类型,游标等元素的组织单元,包存储于数据库中。包提升了PL/SQL的代码组织逻辑,使程序的组织更有逻辑性,也使PL/SQL的封装性更强,对外暴露接口,隐藏具体的实现细节,同时由于包在第一次使用时就被加载入内存,包级别的数据就是一个会话(SESSION)级数据,所以对程序性能也有提升,此外由于不同程序组件直接看到的只是彼此暴露的接口,所以如果修改了包的实现逻辑,依赖于包暴露的接口的程序并不需要重编译,最小化了程序修改时需要重编译的程序单元数量。
#声明包
包由两部分构成——包头和包体。
##包头
包头是包对外暴露的程序元素的规格说明,是对外的接口,并不包括具体的实现,包头是必须的。只要对包本身有访问权限,包头中声明的程序元素就能从外部被访问,这些元素是公有元素。
CREATE [OR REPLACE] PACKAGE package_name
{ IS | AS }
[definitions of public TYPES
,declarations of public variables, types, and objects
,declarations of exceptions
,pragmas
,declarations of cursors, procedures, and functions]
END [package_name];
##包体
包体一般是对包头中暴露的程序元素的实现,包体是可选的,如果包头中暴露的程序元素并不需要实现,也没有额外的计算需要执行,则可以省略包体,包体中除了需要有在包头中声明的公共元素之外,也可以声明额外的元素,这类元素只能被定义在包中的元素范围,是私有元素。
CREATE [OR REPLACE] PACKAGE BODY package_name
{ IS | AS }
[definitions of private TYPEs
,declarations of private variables, types, and objects
,full definitions of cursors
,full definitions of procedures and functions]
[BEGIN
--initiate package
sequence_of_statements
[EXCEPTION
exception_handlers ] ]
END [package_name];
包体也可以存在一个可选的初始化执行区,在该区域可以完成包所需要的复杂初始化或者验证工作,该区域的代码将在会话中第一次使用这个包时被执行,并且只会被执行一次。
#包的使用
包的使用遵循语法:
package_name.package_element
比如常见的:
DBMS_OUTPUT.put_line('string');
#有状态的包
如果包中直接声明了变量或常量,则包就是有状态的。不同于声明在函数或过程中的变量或常量,这类变量或常量在函数或过程结束后就被销毁,而对于直接声明在包中的变量或常量,生命周期则为整个会话(SESSION)期间,这类变量叫做包数据,也叫全局变量(常量)。
#重载
PL/SQL支持重载(overload),可以声明具有相同名称,但却具有不同的参数列表的函数或过程,在任何声明区域都可以有重载,但是重载一般用于包中。
CREATE OR REPLACE PACKAGE common_output
IS
PROCEDURE put_line (value_in IN VARCHAR2);
PROCEDURE put_line (value_in IN BOOLEAN);
END common_output;
使用时,编译器会根据提供的参数选择正确的重载函数(过程)。
使用重载时,参数的数据类型应该具有区分性,比如两个过程唯一的区别在于唯一的参数的类型一个为VARCHAR2
,一个为CHAR
。
PROCEDURE put_line (value_in IN VARCHAR2);
PROCEDURE put_line (value_in IN CHAR);
过程和函数可以有完全相同的名称和参数列表。