您的位置:首页 > 数据库 > Oracle

Oracle PL/SQL学习之 程序包 触发器

2012-11-22 22:51 543 查看
程序包,什么是程序包,百度一下:一篇很详细的文章:ctrl + c 、ctrl + v、update 、publish then见下文

从概念到示例—Oracle创建程序包

一、程序包的相关知识

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;

/

本人观点:

1.使用包更好的实现了封装,更像面向对象了

2.平时也经常用到oracle自身的一些程序包,比如:DBMS_OUTPUT包 、DBMS_RANDOM包等等

3.这里讲到的Type 类型定义不太懂,还得继续study study.....
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: