一、包

  包是一组相关过程、函数、常量、变量、游标、异常等PL/SQL程序设计元素的组合。它类似于C++和Java中的类,其中变量相当于类中的成员变量,过程和函数相当于类中的方法。通过使用包,可以使开发人员利用面向对象的方法进行存储过程的开发,从而提高系统的性能。

  包的结构如下:

  一个包由包头和包主体组成:

  • 包头(package):包头部分声明包内数据类型、变量、常量、游标、子程序(只有声明)和异常错误处理等元素,这些元素为包的共有元素。
  • 包主体(package body):包主体则是包定义部分的具体实现,它负责为包头中所声明包的私有元素。

  包头和包主体分开编译,并作为两个分开的对象存放在数据库数据字典中。

  包的大体语法如下:

  包头语法:

  CREATE OR REPLACE PACKAGE 包名称 IS
   FUNCTION 函数名称(参数 参数类型) RETURN 参数类型; 
  PROCEDURE 存储过程名称( 参数 输入输出类型 参数类型,参数 输入输出类型 参数类型) ;
  end;

  包体语法:

  create or replace package body 包名称 is
    function 函数名称(参数名称 参数类型) return 参数类型 is
    begin
      处理语句
      return 参数;
    end;
    procedure 存储过程名称( 参数 输入输出类型 参数类型,参数 输入输出类型 参数类型 ) is
    begin
      处理语句;

      commit;
    end;
  end;

二、示例代码

  示例如下:

--包头
CREATE OR REPLACE PACKAGE fkpackage IS
v_comm NUMBER := 200 ; --每月奖金200
--定义结构体
type re_person is record(
rid person.id%type,
rusername person.username%type,
rage person.age%type,
rpassword person.password%type
);
--定义游标
type t_person is ref cursor;
--计算年薪的函数
FUNCTION get_year_sal (v_sal NUMBER) RETURN NUMBER ; --定义过程
PROCEDURE pro_person_add (
v_id NUMBER,
v_username VARCHAR2,
v_age NUMBER,
v_password VARCHAR2
) ;
procedure get_person(
v_id in number,
c_person out t_person
);
END fkpackage ;
--包体
create or replace package body fkpackage is
-- 函数
function get_year_sal (v_sal NUMBER) RETURN NUMBER IS
BEGIN
RETURN (v_sal + v_comm) * 12 ;
END;
--过程
procedure pro_person_add(v_id number, v_username varchar2, v_age number, v_password varchar2) is
BEGIN
INSERT INTO person VALUES (v_id, v_username, v_age, v_password);
COMMIT;
END;
procedure get_person(v_id in number, c_person out t_person) is
begin
open c_person for select id,username,age,password from person;
end;
END;

  调用代码:

declare
r_person fkpackage.t_person; --定义包中结构体变量
record_person fkpackage.re_person;
v_id number;
begin
--使用及遍历包中过程返回的结果集
dbms_output.put_line('年薪='||fkpackage.get_year_sal(12000));
v_id := 1;
fkpackage.get_person(v_id, r_person);
loop
fetch r_person into record_person;
exit when r_person%notfound;
dbms_output.put_line('姓名='||record_person.rage);
end loop;
-- 添加数据
fkpackage.pro_person_add(10001, 'zhangsan', 20, '');
end;

三、 PL/SQL包的优点
包提供了几个优点:模块化、方便应用程序设计、信息隐藏、附加功能和良好的性能。

1、 模块化
  包能让我们把逻辑相关的类型、常量、变量、异常和子程序等放到一个命名的PL/SQL模块中。每一个包都容易理解,包与包之间接口简单、清晰。这将有助于程序开发。

2、 轻松的程序设计 设计应用程序时,我们首先要确定的是包说明中的接口信息。我们可以在没有包体的条件下编写并编译说明部分。然后引用该包的存储子程序也会被编译。在完成整个应用程序之前,我们是不需要完全实现包体部分的。

3、 信息隐藏
  有了包,我们就可以指定哪些类型、常量、变量、异常和子程序等是公有(可见和可访问)或私有(隐藏和不可访问)。例如,如果一个包里包含了四个子程 序,其中三个是公有的一个是私有的。包就会隐藏私有子程序的实现,这样的话,如果实现内容发生改变,受到影响的只有包本身(不是我们的应用程序)。同样, 对用户隐藏实现细节也能保证包的完整性。

4、 附加功能
  打包公有变量和游标在一个会话期会一直存在。所以,它们可以被当前环境下的所有子程序共享。并且它们允许我们跨事务来维护数据而不用把它保存在数据库中。

5、 良好的性能
  在我们首次调用打包子程序时,整个包就会被加载到内存中。所以,以后调用包中的相关子程序时,就不需要再次读取磁盘了。包能阻塞级联依赖,这样就能避免不必要的编译。例如,如果我们改变打包函数的实现,Oracle不需要重新编译调用子程序,因为它们并不依赖于包体。

四、系统中的包
Oracle和各种Oracle工具都提供了系统包来帮助我们建立基于PL/SQL的应用程序。下面介绍一下其中比较典型的包。

1、 关于DBMS_ALERT包
  DBMS_ALERT能让数据库触发器在特定的数据库值发生变化时向应用程序发送报警。报警是基于事务的并且是异步的(也就是它们的操作与定时机制无关)。例如,当新的股票和债券上市时公司就可以通过这个包更新来他的投资总额。

2、 关于DBMS_OUTPUT包
  包DBMS_OUTPUT能让我们显示来自PL/SQL块和子程序中的输出内容,这样就会很容易地进行测试和调试。过程put_line能把信息输 出到SGA的一个缓存中。我们可以通过调用过程get_line或在SQL*Plus中设置SERVEROUTPUT ON就能显示这些信息。

3、 关于DBMS_PIPE包
  包DBMS_PIPE允许不同的会话通过命名管道来进行通信(管道就是一块内存区域,进程使用这个区域把消息传递给另外一个进程)。我们可以使用过 程pack_message和send_message把消息封装到一个管道,然后把消息发送到同一个实例中的另一个会话中。 管道的另一个终端,我们可以使用过程recieve_message和unpack_message来接受并打开要读取的消息。命名管道在很多地方都很有用。例如,我们可以用C语言编写一个收集信息的程序,然后把信息通过管道传递给存储过程。

4、关于UTL_FILE包

  包UTL_FILE能让我们的PL/SQL程序读写操作系统(OS)文本文件。它提供了标准的OS流文件I/O,包括open、put、get和close操作。当我们想要读写文件的时候,我们可以调用函数fopen,它能返回一个在后续过程调用中使用到的文件句柄。例如,过程put_line能往打开的文件中写入文本字符串,并在后边添加一个换行符,过程get_line能从打开的文件读取一行内容到放到一个输出缓存中。

5、关于UTL_HTTP包
  包UTL_HTTP可以让我们PL/SQL程序使用超文本传输协议(HTTP)进行通信。它可以从互联网接收数据或调用Oracle Web服务器的cartridge。这个包有两个入口点,每一个都接受一个URL(统一资源定位器)字符串,然后连接到一个指定的网站并返回所请求的数 据,这些数据通常是超文本标记语言HTML格式。

PL/SQL之--包的更多相关文章

  1. PL/SQL之包

    1.包的定义 一个包由两个独立的部分组成--包头和包体.给部分被单独地存放在数据字典中. .1定义包头 语法: CREATE [OR REPLACE] PACKAGE [schema.] packag ...

  2. PL/SQL编程—包

    1.PLSQL 中的包就相当于java中的package,主要好处有(1)防止命名污染,(2)功能统一,(3)允许重载,(4)可以隐藏核心代码,(5)最重要的就是断开依赖链. 2.对于一个程序需要大量 ...

  3. PL/SQL 09 包 package

    --定义包头 create or replace package 包名as  变量.常量声明;  函数声明;  过程声明;end; --定义包体 create or replace package b ...

  4. Insert BLOB && CLOB from PL/SQL and JDBC

    For PL/SQL 1)Create Directory Where BLOB resides. create or replace directory temp as '/oradata2'; - ...

  5. Oracle基础(五)pl/sql进阶(分页过程)

    编写分页过程         通过pl/sql实现分页过程,再该过程中由简单到难一步步深入,目的在于通过该案例熟悉pl/sql的各种存储过程,包,游标.怎样在java中调用等内容的学习. 1.无返回值 ...

  6. 使用集成SOA网关的PL / SQL中的REST

    使用集成SOA网关的PL / SQL中的REST Oracle电子商务套件集成SOA网关(ISG)是一款开箱即用的模块,支持在Oracle Integration Repository中发布支持的接口 ...

  7. Oracle PL/SQL入门之慨述

    Oracle PL/SQL入门之慨述 一.PL/SQL出现的目的 结构化查询语言(Structured Query Language,简称SQL)是用来访问关系型数据库一种通用语言,它属于第四代语言( ...

  8. PL/SQL -->隐式游标(SQL%FOUND)

    PL/SQL -->隐式游标(SQL%FOUND) 分类: SQL/PLSQL 基础2010-12-22 16:23 4084人阅读 评论(0) 收藏 举报 sqlexceptionoracle ...

  9. PL/SQL重新编译包无反应

    前几天碰到一个有趣的事情:早上同事执行一个包很久没有反应,就中断了执行,发邮件让我帮忙查看具体情况,我用PL/SQL Developer登录后,找到这个包的过程中发现这个包的图标有红色叉叉,也就是说这 ...

随机推荐

  1. 【Win10】单元测试中捕获异步方法的指定异常

    温馨提醒:本文需要知道什么是单元测试才能阅读. 在之前 WPF.ASP.NET 中,单元测试要捕捉指定异常,我们是通过 ExpectedExceptionAttribute 来实现的.如下图: 但是, ...

  2. ok6410 android driver(9)

    In this essay, I will write the JNI to test our leds device. If you don't know how to create a jni p ...

  3. C#字符串的恒定性

    string str1="aa"; string str2="aa"; str1,str2,变量所指向的堆空间的地址是一样的.栈空间的内容是不一样的. //ne ...

  4. 重构第29天 去除中间人对象(Remove Middle Man)

    理解:本文中的”去除中间人对象”是指把 在中间关联而不起任何其他作用的类移除,让有关系的两个类直接进行交互. 详解:有些时候在我们的代码会存在一些”幽灵类“,设计模式大师Martin Fowler称它 ...

  5. 因用了NeatUpload大文件上传控件而导致Nonfile portion > 4194304 bytes错误的解决方法

    今天遇到一个问题,就是“NeatUpload大文件上传控件而导致Nonfile portion > 4194304 bytes错误”,百度后发现了一个解决方法,跟大家分享下: NeatUploa ...

  6. sql date()函数,时间格式

    (1).GETDATE() 函数从 SQL Server 返回当前的日期和时间. 语法 GETDATE() 实例 下面是 SELECT 语句: SELECT GETDATE() AS CurrentD ...

  7. 分享一个C#的分页类

    废话不说只有代码: using System.Linq; using System.Collections.Generic; namespace CommonLibrary { public clas ...

  8. java阻塞队列

    对消息的处理有些麻烦,要保证各种确认.为了确保消息的100%发送成功,笔者在之前的基础上做了一些改进.其中要用到多线程,用于重复发送信息. 所以查了很多关于线程安全的东西,也看到了阻塞队列,发现这个模 ...

  9. U-boot的环境变量值得注意的有两个: bootcmd 和bootargs

    本文转载至:http://www.cnblogs.com/cornflower/archive/2010/03/27/1698279.html U-boot的环境变量值得注意的有两个: bootcmd ...

  10. JMS学习(三)JMS 消息结构之属性及消息体详解

    一.前言 通过上一篇的学习我们知道了消息分为三个部分,即消息头,属性及消息体,并对消息头的十个属性进行了详细的介绍,本文再对消息属性及消息体进行详细的介绍. 二.属性介绍 消息属性的主要作用是可以对头 ...