可以利用包(package)将过程和函数安排在逻辑分组中。
包含有两个分离的部件:包说明(规范、包头)和包体(主体)。
包说明和包体都存储在数据字典中。
包与过程和函数的一个明显的区别是,包仅能存储在非本地的数据库中。
用SQL命令创建包需要分别创建包头和包体两部分:
--包头 create or replace package 包名 is/as 定义(过程、函数等) function 名称(参数名称 in/out 类型) return 类型;
在定义包头时,要遵循以下规则:
①包元素的位置可以任意安排。然而,在声明部分,对象必须在引用前进行声明。
②包头可以不对任何类型的元素进行说明。例如,包头可以只带过程和函数说明语句,而不声明任何异常和类型。
③对过程和函数的任何声明都必须只对子程序和其参数(如果有的话)进行描述,但不带任何代码的说明,实现代码则只能在包体中。它不同于块声明,在块声明中,过程或函数的代码同时出现在其声明部分。
--包体 create or replace package body 包名 //or replace :如果新创建的包体名有重复的则不进行创建,或是删了之前创建的同名包体名才可以创建 is/as function 名称(参数名称 in/out 类型) return 类型; begin end; end 包名;
说明:包体中的PL/SQL程序部分可以是游标函数,过程的具体定义
包体是一个独立于包头的数据字典对象,包体只能在包头完成编译后才能进行编译,包体中带有实现包头中描述的前向子程序的代码段。除此之外,包体还可以包括具有包体全局属性的附加声明部分,但这些附加说明对于说明部分是不可见的。
删除包:
如果只是删除包体,则使用如下命令:
drop package body<包名>;
如果要同时删除包头和包体,则使用如下命令:
drop package<包名>;
应用前面统计全体同学的平均成绩的函数和定义从学生成绩表中每个同学各门功课的成绩的过程创建包TEST_PACKGE。
--包头 create or replace package TEST_PACKGE as function stu_avg return number; end TEST_PACKGE; --包体 create or replace package body TEST_PACKGE as function stu_avg return number as v_avg number; begin select avg(result_number) into v_avg from school_result; return v_avg; end stu_avg; end TEST_PACKGE; --包的使用 declare begin dbms_output.put_line(TEST_PACKGE.stu_avg); end;
--包的删除
drop package BODY TEST_PACKGE;
drop package TEST_PACKGE;
包的初始化
当第一次调用打包子程序时,该包将进行初始化。也就是说,将该包从硬盘中读入到内存,并启动调用的子程序的编译代码。这时,系统为该包中定义的所有变量分配内存单元。每个会话都有其打包变量的副本,以确保执行同一包子程序的两个对话使用不同的内存单元。
在大多数情况下,初始化代码要在包第一次初始化时运行。为了实现这种功能,可以在包体中的所有对象之后加入一个初始化部分。
--语法格式: create or replace package stu_avg_pk as begin end; end stu_avg_pk;
重载:
在包的内部,过程和函数可以被重载,也就是说,可以有一个以上的名称相同但参数不同的过程或函数。由于重载允许相同的操作施加在不同类型的对象上,因此,它是PL/SQL语言的一个重要特征。
--使用学生姓名或学号,查询学生的平均分数 create or replace package stu_avg_pk as function stu_avg(v_stu_id in char) return number; function stu_avg(v_stu_name in char,v_stu_sex in char) return number; end stu_avg_pk;
重载要受到下列限制:
(1) 如果两个子程序的参数仅在名称和类型上不同,这两个子程序不能重载。例如,下面的函数是不能进行重载:
procedure overloadMe(p_theparameter IN number);
procedure overloadMe(p_theparameter OUT number);
(2) 不能仅根据两个子程序不同的返回类型对其进行重载。例如,下面的函数是不能进行重载:
function overloadMeToo return date;
function overloaMeToo returen number;
(3) 重载子程序的参数的类族(type family)必须不同。例如,由于CHAR和VARCHAR2属于同一类族,所以下面的过程不能重载:
procedure overloadChar(p_theparameter IN char);
poecedure overloadchar(p_theparameter IN varchar2);
根据用户定义的对象类型,打包子程序也可以重载。
Oracle内置包:
Oracle提供了若干具有特殊功能的内置包。这些具有特殊功能的包为:
DBMS_ALERT包:用于数据库报警,允许会话间通信。
DBMS_JOB包:用于任务调度服务。
DBMS_LOB包:用于大型对象操作。
DBMS_PIPE包:用于数据库管道,允许会话间通信。
DBMS_SQL包:用于执行动态SQL。
UTL_FILE包:用于文本文件的输入与输出。
除了包UTL_FILE既存储在服务器端又存储在客户端,所有的DBMS包都存储在服务器中。此外,在某些客户环境,Oracle还提供一些额外的包。