程序包由PL/sql程序元素(如变量、类型)和匿名PL/sql块(如游标)、命名PL/sql块(如存储过程和函数)组成。程序包可以被整体加载到内存中,这样就可以大大加快程序包中任何一个组成部分的访问速度。
1、程序包的规范
该“规范”用于规定在程序包中可以使用哪些变量、类型、游标和子程序(指各种命名的PL/sql块),需要注意的是:程序包一定要在“包主体”之前被创建,其语法格式如下:create [or replace ] package pack_name is [declare_variable]; [declare_type]; [declare_cursor]; [declare_function]; [declare_ procedure]; end [pack_name];
pack_name:程序包的名称,如果数据库中已经存在了此名称,则可以指定“or replace”关键字,这样新的程序包将覆盖掉原来的程序包。
declare_variable:规范内声明的变量。
declare_type:规范内声明的类型。
declare_cursor:规范内定义的游标。
declare_function:规范内声明的函数,但仅定义参数和返回值类型,不包括函数体。
declare_ procedure:规范内声明的存储过程,但仅定义参数,不包括存储过程主体。
【实例】创建一个程序包的“规范”,首先在该程序包中声明一个可以获取指定部门的平均工资的函数,然后在声明一个可以实现按照指定比例上调指定职务的工资的存储过程,代码如下:
create or replace package pack_emp is function fun_avg_sal(num_deptno number) return number;--该函数用于获取指定部门的平均工资 procedure pro_regulate_sal(var_job varchar2,num_proportion number);--该存储过程实现按照指定比例上调指定职务的工资 end pack_emp;
2、程序包的主体
程序包的主体包含了在规范中声明的游标、过程和函数的实现代码,另外,也可以在“程序包的主体”中声明一些内部变量。程序包主体的名称必须与规范的名称相同,这样通过这个相同的名称Oracle就可以将“规范”和“主体”结合在一起组成程序包,并实现一起进行代码编译。
【实例】创建程序包pack_emp的主体,在该主体中实现对应“规范”中声明的函数和存储过程,代码如下:
create or replace package body pack_emp is function fun_avg_sal(num_deptno number) return number is --引入“规范”中的函数 num_avg_sal number;--定义内部变量 begin select avg(sal) into num_avg_sal from emp where deptno = num_deptno;--计算某个部门的平均工资 return(num_avg_sal);--返回平均工资 exception when no_data_found then--若未发现记录 dbms_output.put_line('该部门编号不存在雇员记录'); return 0;--返回0 end fun_avg_sal; procedure pro_regulate_sal(var_job varchar2,num_proportion number) is--引入“规范”中的存储过程 begin update emp set sal = sal*(1+num_proportion) where job = var_job;--为指定的职务调整工资 end pro_regulate_sal; end pack_emp;
在创建了程序包的“规范”和“主体”之后,就可以像普通的存储过程和函数一样调用了。
【实例】通过程序包pack_emp调用其中的函数和存储过程,代码如下:declare num_deptno emp.deptno%type;--定义部门编号变量 var_job emp.job%type;--定义职务变量 num_avg_sal emp.sal%type;--定义工资变量 num_proportion number;--定义工资调整比例变量 begin num_deptno:=10;--设置部门编号为10 num_avg_sal:=pack_emp.fun_avg_sal(num_deptno);--计算部门编号为10的平均工资 dbms_output.put_line(num_deptno||'号部门的平均工资是:'||num_avg_sal);--输出平均工资 var_job:='SALESMAN';--设置职务名称 num_proportion:=0.1;--设置调整比例 pack_emp.pro_regulate_sal(var_job,num_proportion);--调整指定部门的工资 end;