一、什么要使用包?

       在一个大型项目中,可能有很多模块,而每个模块又有自己的过程、函数等。而这些过程、函数默认是放在一起的(如在PL/SQL中,过程默认都是放在一起 的,即Procedures中),这些非常不方便查询和维护,甚至会发生误删除的事件。

PL/SQL为了满足程序模块化的需要,引入了包的构造。通过使用包就可以分类管理过程和函数等。

(1)包是一种数据库对象,相当于一个容器。将逻辑上相关的过程、函数、变量、常量和游标组合成一个更大的单位。用户可以从其他 PL/SQL 块中对其进行引用

(2)包类似于C++和JAVA语言中的类,其中变量相当于类中的成员变量,过程和函数相当于类方法。把相关的模块归类成为包,可使开发人员利用面向对象的方法进行开发,具有面向对象程序设计语言的特点,

(4)PL/SQL的包具有信息隐蔽性(information hiding),仅在算法和数据结构设计有关层可见。可将过程说明和过程体组成一个程序单位。也可将过程说明与它的过程体分开。也可在包中定义过程,而该过程在包说明中没有定义过程说明,这样定义的过程仅在包内使用。

(5)在PL/SQL程序设计中,使用包不仅可以使程序设计模块化,对外隐藏包内所使用的信息(通过使用私用变量),而写可以提高程序的执行效率。因为,当程序首次调用包内函数或过程时,ORACLE将整个包调入内存,当再次访问包内元素时,ORACLE直接从内存中读取,而不需要进行磁盘I/O操作,从而使程序执行效率得到提高。

二、包结构

一个包由两个分开的部分组成:包规范包体

2.1包定义(PACKAGE)

(1) 包定义(PACKAGE):包定义部分是为应用程序的接口,声明包内数据类型、变量、常量、游标、子程序和异常错误处理等元素,这些元素为包的公有元素。

CREATE [OR REPLACE] PACKAGE package_name

  {IS | AS}

   [公有数据类型定义]

   [公有游标声明]

   [公有变量、常量声明]

   [公有子程序声明]

END   [package_name];

2.2包主体(PACKAGE BODY)

包主体(PACKAGE BODY):包主体则是包定义部分的具体实现,它定义了包定义部分所声明的游标和子程序,在包主体中还可以声明包的私有元素。如果在包主体中的游标或子程序并没有在包头中定义,那么这个游标或子程序是私有的。

CREATE [OR REPLACE] PACKAGE BODY package_name

{IS | AS}

                   [私有数据类型定义]

                   [私有变量、常量声明]

                   [私有子程序声明和定义]

                   [公有子程序定义]

BEGIN

                   执行部分(初始化部分)

END [package_name];

与类相同,包中的程序元素也分为公用元素和私用元素两种,这两种元素的区别是他们允许访问的程序范围不同,即它们的作用域不同。公用元素不仅可以被包中的函数、过程所调用,也可以被包外的PL/SQL程序访问,而私有元素只能被包内的函数和过程序所访问。

包定义和包主体分开编译,并作为两部分分开的对象存放在数据库字典中。包定义一定要在包主体前面编译,包主体可以没有,但包定义一定要有) 包的名称和包体的名称要保持一致

三、包举例

定义包规范

CREATE OR REPLACE
package p_stu
as
--定义结构体
type re_stu is record(
rname student.name%type,
rage student.age%type
);
--定义游标
type c_stu is ref cursor;
--定义函数
function numAdd(num1 number,num2 number)return number;
--定义过程
procedure GetStuList(cid in varchar2,c_st out c_stu);
end;

说明 type c_stu is ref cursor;

type c_stu:定义类型变量

is ref cursor:相当于数据类型,不过是引用游标的数据类型

这种变量通常用于存储过程和函数返回结果集时使用,因为PL/SQL不允许存储过程或函数直接返回结果集,但可以返回类型变量,于是引用游标的类型变量作为输出参数或返回值就应运而生了。

定义包体:

CREATE OR REPLACE
package body p_stu
as
--游标和结构体,包规范中已声明,包体中不用再声明,直接使用。 --实现方法
function numAdd(num1 number,num2 number)return number
as
num number;
begin
num:=num1+num2;
return num;
end; --实现过程
procedure GetStuList(cid varchar2,c_st out c_stu)
as
r_stu re_stu; --直接使用包规范中的结构
begin
open c_st for select name,age from student where classid=cid;
-- 如果已经在过程中遍历了游标,在使用这个过程的块中,将没有值。
-- loop
-- fetch c_st into r_stu;
-- exit when c_st%notfound;
-- dbms_output.put_line('姓名='||r_stu.rname);
-- end loop;
end;
end;

调用包

declare
c_stu p_stu.c_stu; --定义包中游标变量
r_stu p_stu.re_stu; --定义包中结构体变量
num number;
begin
--使用及遍历包中过程返回的结果集
p_stu.GetStuList('5',c_stu);
loop
fetch c_stu into r_stu;
exit when c_stu%notfound;
dbms_output.put_line('姓名='||r_stu.rname);
end loop; --使用包中的方法
select p_stu.numAdd(5,6) into num from dual;
dbms_output.put_line('Num='||num);
end;

参考

Oracle 包(Package)

第七章 程序包的创建和应用

Oracle 中包(Package)的更多相关文章

  1. Oracle中包的创建

    包是过程和函数的集合体,包包括创建包和创建包体,创建包的时候在可以定义过程和函数,包体中则具体实现过程和函数. eg: --创建包 create  or replace package mypac1 ...

  2. Oracle 中包的应用

    包由两个分离的部分组成:包头(PACKAGE)和包体(PACKAGEBODY).包头是包的说明部分,是对外的操作接口,对应用是可见的;包体是包的代码和实现部分,对应用来说是不可见的黑盒.        ...

  3. oracle数据库包package小例子

    为了把某一个模块的函数.存储过程等方便查询维护,可以把它们打到一个包里.下面给出一个简单的小例子. 1.创建包头 create or replace package chen_pack is func ...

  4. Oracle中定义package以及存储过程的使用

    使用scott账户下的dept表: select * from dept order by deptno; 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 S ...

  5. java实现调用ORACLE中的游标和包

    今天把oracle中的包和游标学习了下,不废话,网上的的有些代码是错误的,抄来抄去,就自己实践了下,做个记录.直接上图,上代码 通过plsql创建自己的的包,包分为包头和包体. 1.包头如下: CRE ...

  6. Oracle中 Package与Package body的介绍

    1.Oracle Package的作用: 可以简化应用设计.提高应用性能.实现信息隐藏.子程序重载 2.ORACLE中的function   .package.package   bodies.pro ...

  7. Oracle中如何导出存储过程、函数、包和触发器的定义语句?如何导出表的结构?如何导出索引的创建语句?

    Oracle中如何导出存储过程.函数.包和触发器的定义语句?如何导出表的结构?如何导出索引的创建语句? QQ群里有人问:如何导出一个用户下的存储过程?   麦苗答:方法有多种,可以使用DBMS_MET ...

  8. Oracle 存储过程包(Package、Package Body)

    初出茅庐,不知原来存储过程还可以写得如此复杂,而且还竟然可以调试! 好吧,得整理一下存储过程的一些语法,以备以后用到时可以查阅. 使用数据库:Oracle 数据库工具:PL/SQL Developer ...

  9. oracle中的创建过程,函数,包

    一.创建存储过程 存储过程是在oracle中存取完成特定业务逻辑的代码块.存储过程是命名块,匿名块不存在数据库中,命名块会存储到数据库中,匿名块每次运行都需要提前编译,命名块一次存储,只会编译一次.命 ...

随机推荐

  1. Material Designer的低版本兼容实现(六)—— Ripple Layout

    新版的Android5.0添加了涟漪效果,虽然开源的库提供了各种控件便于大家使用涟漪效果.但是仍旧不可能满足所有需求,因此我今天改出来一个类叫做,LayoutRipple,其实感觉跟应该叫Ripple ...

  2. 《Erlang程序设计(第2版)》

    <Erlang程序设计(第2版)> 基本信息 作者: (瑞典)Joe Armstrong 译者: 牛化成 丛书名: 图灵程序设计丛书 出版社:人民邮电出版社 ISBN:9787115354 ...

  3. OpenResty全功能Web应用服务器,打包了标准的 nginx 核心

    OpenResty打包了标准的 nginx 核心,很多的常用的第三方模块,以及它们的大多数依赖项. 通过揉和众多设计良好的 nginx 模块,OpenResty 有效地把 nginx 服务器转变为一个 ...

  4. Apache的三种工作模式

    Web服务器Apache目前一共有三种稳定的MPM(Multi-Processing Module,多进程处理模块)模式. 它们分别是prefork,worker和event,它们同时也代表这Apac ...

  5. [转]ThinkPHP的CURD易忽视点小结

    转自: http://www.oschina.net/code/snippet_2285640_44437. 1.使用对象的方法插入数据 D用法. $Form = D('Form'); $data[' ...

  6. smb与samba

    为了使Windows 主机间的资源能够共享,微软于1980年开发了SMB(Server Message Block)通信协议,并通过SMB通信协议,使网络上各台主机之间能够共享文件.打印机等资源.目前 ...

  7. tcp常见状态

    常见状态 1.建立连接 2.关闭连接

  8. Maven 搭建spring boot多模块项目(附源码),亲测可以,感谢原创

    原创地址:https://segmentfault.com/a/1190000005020589 我的DEMO码云地址,持续添加新功能: https://gitee.com/itbase/Spring ...

  9. storm的一些相关文章

    文章可以看这些: https://www.cnblogs.com/zhaojiankai/p/7257617.html https://blog.csdn.net/wangshuminjava/art ...

  10. 使用JDBC向Kudu表插入中文数据乱码(转载)

    参考:https://cloud.tencent.com/developer/article/1077763 问题描述 使用Impala JDBC向Kudu表中插入中文字符,插入的中文字符串乱码,中文 ...