1.概述
包是使用包名进行分组的PL/SQL语句块的集合。将逻辑上相关联的PL/SQL类型、变量常量、过程、函数、游标和异常封装在一起。将“包”看作一个“应用程序”。
优势:模块化;更容易的应用设计;更好的性能;公共变量可在会话期间被所有子程序共享。
2.定义
包头:
--含有包的内容的相关信息(全局或公开变量的声明)。
--若定义游标、子程序,则一定要在包体中实现;
--可实现子程序重载。
--语法:
create or replace PACKAGE package_name
is
[declarations of variables and types]
[specifications of cursors]
[specifications of modules]
end package_name;
包体:
--含有包头中所描述对象的实际可执行代码。也有包头中未声明对象的代码(称为私有对象)。
--可以包含包头中未定义的常量变量、游标、子程序等,但在包外不可调用它们。
--语法:
Create or replace PACKAGE BODY package_name
is
[declarations of variables and types]
[specification and select statement of cursors]
[specification and body of modules]
[begin
executable statements]
[exception
exception handlers]
end package_name;
关于编译:
--包头重新编译后,包体会变成invalid,需做对应修改后再编译,包体状态才会变为valid。
--包体重新编译后,包头不会变成invalid。
-- alter package schema.package_name compile [package|specification|body]
参数说明:
package:包头和包体重新编译。
specification:包头重新编译。
body:包体重新编译
包体的规则:
游标和模块头部以及它们在包规范中的定义,必须是准确匹配的。
不要在包体中重复包头中对变量、异常、类型和常量的声明。
包规范中的声明任何元素都可以在包体中引用。引用语法:package_name.element.
3.示例
包头(包规范):
create or replace package manage_students
as
v_current_time date; --全局公有变量 v_currnet_time
--存储过程声明
procedure find_name(i_student_id in student.student_id%type,
o_first_name out student.FIRST_NAME%type,
o_last_name out student.LAST_NAME%type);
--函数声明
function id_is_good(i_student_id in student.STUDENT_ID%type)
return boolean;
end manage_students;
create or replace package body manage_students
as
v_num constant number:=1; --私有常量
v_sys varchar2(10);--私有变量
--存储过程实现
procedure find_name(i_student_id in student.student_id%type,
o_first_name out student.FIRST_NAME%type,
o_last_name out student.LAST_NAME%type)
is
v_student_id student.STUDENT_ID%type;
begin
select first_name,last_name into o_first_name,o_last_name from student
where student_id=i_student_id;
EXCEPTION
when others then
dbms_output.put_line('Error is finding student_id:'||v_student_id);
end find_name;
--函数实现
function id_is_good(i_student_id in student.STUDENT_ID%type)
return boolean
is
v_id_cnt number;
begin
select count(*) into v_id_cnt from student where student_id=i_student_id;
return 1=v_id_cnt;
exception
when others then return false;
end id_is_good;
--包体自忆的私有函数
function student_count_priv --此函数数是包体私有的
return number
is
v_count number;
begin
select count(*) into v_count from student;
return v_count;
exception
when others then return (0);
end student_count_priv;
--给全局变量赋值
begin
select sysdate into v_current_time from dual;
end manage_students;