1. 程序包(package)用于将逻辑相同的PL/SQL块或元素(变量、常量、自定义数据类型、过程、函数、游标)组织在一起,作为一个完整的单元被存储在数据库中,以名称来标识。它具有面向对象的程序设计语言的特点,是对PL/SQL块和元素的封装。程序包类似java语言中类,其中变量类似java类中的成员变量,过程和函数类似java类中方法。
2. 程序包包括两个部分,一个是说明部分(specification),一个包体部分(body)。
3. Specification是package与应用程序之间的接口。用于定义包的公有组建,包括变量、常量、过程、函数、游标等。同时在包说明中定义的公有组建不仅可以在包内使用,还可以由其他过程和函数使用。
注意:定义包说明的时候,不应该将所有的组建都放在包说明处进行定义,而应该只定义公有组建。创建包的语法格式:
4. 举例创建一个包说明,包括一个记录变量v_deptrec,两个用于保存内置异常错误函数sqlcode和sqlerrm返回值的变量、两个函数、两个过程。记录变量v_deptrec与表dept结构相同。代码如下:
5. 包体是包的具体实现。在其中可以定义私有组建,可以定义公有游标,实现在包说明中说明的过程、函数。
注意:包体只能在包说明被编译之后才能被编译。
在包说明中的过程、函数名称必须严格地包体中实现部分的过程、函数名称相匹配
在包体中声明的数据类型、常量、变量都是私有的,只能在包体中使用。但在包体中可以使用在包说明中声明的数据类型、变量、常量。
在包体的执行部分可以对包说明中声明的变量进行初始化。因为包不能传递参数,所以只能通过这种方法进行初始化。包的初始化只在第一次调用包的时候运行一次。
创建包体的语法格式:
6. 举例说明:针对上面举例的包说明my_pkg,来说明一个包体的案例(敲这个包体累死我了,真麻烦)
create or replace package body my_pkg
is
pragma serially_reusable;
--私有变量说明
v_flag number;
--私有游标说明
cursor mycursor is
select deptno,dname from dept;
--私有函数声明和定义
function check_dept(v_deptno number)
return number
is
begin
select count(*) into v_flag from dept where deptno = v_deptno;
if v_flag > 0 then
v_flag := 1;
end if;
return v_flag;
end check_dept;
--公有函数定义add_dept
function add_dept(v_deptno number,
v_deptname varchar2,
v_deptloc varchar2)
return number
is
begin
if check_dept(v_deptno) = 0 then
insert into dept values(v_deptno,v_deptname,v_deptloc);
return 1;
else
return 0;
end if;
exception
when others then
v_sqlcode := sqlcode; --捕获异常错误信息
v_sqlerrm := sqlerrm;
return -1;
end add_dept;
--公有函数定义remove_dept
function remove_dept(v_deptno number)
return number
is
begin
if check_dept(v_deptno) = 1 then
delete from dept where deptno = v_deptno;
return 1;
else
return 0;
end if;
exception
when others then
v_sqlcode := sqlcode; --捕获异常错误信息
v_sqlerrm := sqlerrm;
return -1;
end remove_dept;
--公有过程定义query_dept
procedure query_dept(v_deptno number)
is
begin
if check_dept(v_deptno) = 1 then
select * into v_deptrec from dept where deptno = v_deptno;
end if;
exception
when others then
v_sqlcode := sqlcode; --捕获异常信息
v_sqlerrm := sqlerrm;
end query_dept;
--公有过程定义read_dept
procedure read_dept
is
v_deptno number;
v_dname varchar2(14);
begin
--用游标式for循环处理游标结果的每一行
for c_mycursor in mycursor loop
v_deptno := c_mycursor.deptno;
v_dname := c_mycursor.dname;
dbms_output.put_line(v_deptno||' '||v_dname);
end loop;
end read_dept;
begin --包体初始化部分,对公有变量进行初始化
v_sqlcode := null;
v_sqlerrm := '初始化信息文本';
end my_pkg;
7. 创建完成程序包说明和程序包体之后就可以对程序包进行调用了,调用格式为“包名.组件”。举例以上述创建的包说明和包体作为依据:
1) 调用包的公有变量:
包中的公有变量在当前会话内,一直有效。
疑问:
2) 调用包的公有函数,很简单,直接截图:
3) 调用包的公有过程,很简单,直接截图:
8. 创建程序包之后,oracle会将程序包及其源代码存放到数据库字典中。通过查询user_source可以显示当前用户所有程序包以及源代码。命令如下:
注意:函数名要大写,SELECT FROM WHERE MY_PKG
9. 删除包
Dorp package body package_name;
Dorp package package_name;