一、程序包的相关知识
1.定义与说明
a. 相关对象的封装
b. 程序包的各部分
- 程序包规格说明
声明子程序
- 程序包主体
定义子程序
2.使用程序包的优点
- 模块化
- 更轻松的应用程序设计
- 信息隐藏
- 新增功能
- 性能更佳
3.公有项和私有项的区别
公有项:在程序包说明部分定义的变量、过程、函数
私有项:在程序包主体部分定义的变量、过程、函数
公有项 私有项
可以在程序包之外引用 不能在程序包之外引用
是在程序包规格说明中定义的 是在程序包主体中定义的
用于全局目的 用于局部目的
二、程序包创建说明
1.程序包规格说明
(1)、使用Create Package命令进行创建
(2)、包含公用对象和类型
(3)、声明类型、常量、变量、异常、游标和子程序
(4)、可以在没有程序包主题的情况下存在
(5)、可以重载
- 程序包中的多个子程序可以具有相同的名称
- 它们的形参是不同的
- 只能位于打包的子程序中
- 限制
a. 如果子程序的参数仅名称或模式不同,则不能重载
b. 不能基于其返回类型重载子程序
2.程序包主体
(1)、使用Create Package body 命令进行创建
(2)、包含子程序和游标的定义
(3)、包含私有声明
(4)、不能在没有程序包规格说明的情况下独立存在
3.程序包的调用
包名.类型名;
包名.函数名[参数表];
包名..过程名[参数表];
(1)、 Package-name.type-name
(2)、 Package-name.object-name
(3)、 Package-name.subprogram-name
其中,Package-name 是程序包名称,type-name是类型名称,
object-name是对象名称,subprogram-name 是子程序名称
--示例
DBMS_output.put_line(Hello);
(4)、对于返回参数是游标类型的调用(如:引用游标)
set autoprint on --打开Sqlplus输出
variable tempCur RefCursor; --定义一个宿主类型的引用游标变量
exec StudentPackage.ReturnStudent(:tempCur); --执行带有引用游标的过程 注意使用宿主类型的变量前面要加“:”符号
4. 有关子程序和程序包的信息
A.数据字典
User_objects 用于检查对象是否存在
User_source 用于获取对象的代码
B. 包的修改和删除
Alter Package [Body] 包名
Alter Package Body StudentPackage;
Drop Package [Body] 包名
Drop Package Body StudentPackage;
5. 创建格式
A.创建包规格部分
格式:Create [or replace] Package 包名
IS|AS
变量声明;
类型定义;
异常声明;
游标声明;
函数说明;
过程说明;
Pragma restrict_references(过程名或函数名,WNDS[,WNPS][,RNDS][,RNPS]) --编译指令 限定函数的操作
End [包名];
B.创建包主体部分
格式: Create [or replace] package body 包主体名 --包主体名一定要是已经定义的包名
IS|AS
变量声明; --具体的实现部分
类型定义;
异常声明;
游标声明;
函数说明;
过程定义;
End [包主体名];
6. 示例
示例1.创建程序包的规格说明部分
Create or replace Package StudentPackage
is
Type curRefStudent is Ref Cursor Return Student%rowtype;
Procedure SelectStudent(FindID in Student.stuid%type);
Procedure InsertStudent(NewStudent in Student%rowType);
Procedure UpdateStudent(NewStudent in Student%rowType);
Procedure DeleteStudent(DelID in Student.stuid%type);
Procedure ReturnStudent(inOutstu in out curRefStudent);
Function RegurnRecordCount Return Number;
End studentPackage;
示例2.创建程序包的主体部分
Create or replace Package Body StudentPackage IS
Procedure SelectStudent(FindID in Student.stuid%type) as --注意没有Create
/*实现查询过程的定义*/
Cursor findCur is select * from student where stuid=FindID;
Begin
For S in FindCur Loop
DBMS_output.put_line(S.stuID||' '||s.StuName||' '||S.Sex);
End Loop;
Exception
When No_Data_Found Then
DBMS_output.Put_Line('没有查到ID为'||FindID||'的记录!');
When Others Then
DBMS_output.Put_Line('查询过程中发生意外情况');
End SelectStudent; --结束查询过程
/*实现插入过程的定义*/
Procedure InsertStudent(NewStudent in Student%rowType) as
iRec Integer;
Not_Exists_Student Exception; --预定义异常
Begin
Select count(*) into iRec from student where stuid=NewStudent.stuID;
IF iRec>0 Then
Raise Not_Exists_Student;
Else
insert into student values(NewStudent.stuid,NewStudent.stuName,NewStudent.sex);
commit;
End IF;
Exception
When Not_Exists_Student Then
DBMS_output.Put_Line('要插入的编号:'||NewStudent.stuid||'的记录已经存在');
When Others Then
DBMS_output.Put_Line('插入记录操作过程中出现错误');
End InsertStudent;--结束插入过程
/*实现更新过程的定义*/
Procedure UpdateStudent(NewStudent in Student%rowType) as
iRec Integer;
Begin
select Count(*) into iRec From student Where stuid=NewStudent.stuid;
IF iRec =0 Then
DBMS_output.Put_Line('编号为:'||NewStudent.stuid||'的记录不存在,修改失败');
ELSE
Update student Set Stuname=NewStudent.stuName,Sex=NewStudent.Sex
WHERE stuid=NewStudent.stuID;
Commit;
End IF;
Exception
When No_Data_Found Then
DBMS_output.Put_Line('编号为:'||NewStudent.stuID||'的记录不存在,修改失败');
When Others Then
DBMS_output.Put_Line('执行修改操作时发生意外情况,修改未成功');
End UpdateStudent;--结束修改过程
/*实现删除过程的定义*/
Procedure DeleteStudent(DelID in Student.stuid%type) as
iRec Integer;
Begin
Select Count(*) into iRec From Student Where stuID=DelID;
IF iRec=0 Then
DBMS_output.Put_Line('编号为:'||DelID||'的记录不存在,删除操作时未成功');
ELSE
Delete From student Where stuid=DelID;
Commit;
DBMS_output.Put_Line('删除成功!');
End IF;
Exception
When Others Then
DBMS_output.Put_Line('执行删除操作时发生意外情况,删除未成功');
End DeleteStudent;
/*实现参数带有游标类型定义*/
Procedure ReturnStudent(inOutstu in out curRefStudent) as
Begin
Open inOutstu For Select * from student;
End ReturnStudent;
/*实现函数定义*/
Function RegurnRecordCount Return Number as
RecCount number(10);
Begin
Select Count(*) into RecCount From student;
Return recCount;
Exception
When Others Then
DBMS_output.Put_Line('查询表中记录数时发生意外情况');
End RegurnRecordCount; --结束函数的定义
End studentPackage;--结束包
示例3:调用包
1. 调用studentPackage包中的InsertStudent过程
Declare
newStu Student%RowType;
Begin
newStu.stuID:='1001';
newStu.stuName:='张三';
newStu.sex:='男';
studentPackage.InsertStudent(newStu);
End;
/
2. 调用studentPackage包中的UpdateStudent过程
Declare
newStu Student%RowType;
Begin
newStu.stuID:='1001';
newStu.stuName:='李四';
newStu.sex:='女';
studentPackage.UpdateStudent(newStu);
Exception
When Dup_Val_On_Index Then
DBMS_output.Put_Line('唯一约束被破坏');
When Others Then
DBMS_output.Put_Line('更新过程出现错误');
End;
/
3. 调用studentPackage包中的DeleteStudent过程
Begin
studentPackage.DeleteStudent('1001');
End;
/
4. 调用studentPackage包中的ReturnRecordCount函数
Begin
DBMS_output.put_Line(studentPackage.ReturnRecordCount);
End;
/