PACKAGE

说明

Package是一组相关过程、函数、变量、常量、类型和游标等PL/SQL程序设计元素的组合。包具有面向对象设计的特点,是对这些PL/SQL程序设计元素的封装。

(1)声明或定义:包定义部分是创建包的规范说明,声明包内数据类型、变量、常量、游标等元素。

这部分也是为使用者提供了透明的接口。

(2)包体:包体是包定义部分的具体实现。

(3)将有联系的对象打成包,方便使用。

(4)包中对象包括储存过程,函数,游标,自定义类型和变量,可以在PL/SQL块中应用这些对象。

创建包

使用CREATE PACKAGE语句创建或替换一个包的规范,包是相关的存储过程、函数、和其他程序对象的集合,在数据库中作为一个单元存储。包规范声明这些对象,在包体中定义这些对象。

  • OR REPLACE:

如果包存在,则重建一个包,并重新编译,在包重定义之前被授予包上的权限的用户仍然可以访问包,而不需要重新授权。

如果任何基于函数的索引依赖该包,则数据库会标记该索引disabled。

  • [EDITIONABLE|NONEDITIONABLE]

标记该package对象是否是可编辑的,目前该功能仅支持语法,默认是EDITIONABLE。

  • Schema

包所在的模式名字。

  • Sharing_clause

该子句指明包使用什么样的共享属性,仅仅支持在application root环境下创建对象。

  • METADATA 共享数据字典,但数据对每个容器是不同的,
  • NONE 该对象不是共享的,只能被application root访问

如果没有指定该子句,则由初始化参数DEFAULT_SHARING决定,如果该参数没有值,则默认是METADATA。

目前仅支持语法。

  • Default collation clause

字符串排序集,仅支持语法。

  • invoker_rights_clause

指定包中函数、存储过程以及包规范中声明的显示游标的AUTHID,目前仅支持语法。

  • accessible_by_clause

指定可以调用该包的每个访问器,目前仅支持语法。

  • item_list_1

定义包中的类型、声明游标和子过程,每个声明必须在包中有其定义。除了空格外,包规范中声明与包体中定义需要严格字符一致。不允许有PRAGMA AUTONOMOUS_TRANSACTION出现,具体内容由普通函数声明部分决定,这部分内容俗称包的公有对象,外部可以通过包名.xxx来引用或赋值。

创建包体

需要有与CREATE PACKAGE一样的权限,且要求包体与包规范在同一个模式下,且包规范必须存在,该语句定义包规范中声明的对象。

当包规范中有cursor或子过程时,那么必须拥有一个包体去定义它,否则包体是可选的。

  • OR REPLACE

如果包体已存在,则重建包体并重新编译包体。

在包体重定义之前被授予包体上权限的用户仍然可以访问包,而不需要重新授权。

  • [EDITIONABLE|NONEDITIONABLE]

如果没有指定这个属性,则从包规范中继承,如果设置了,则需和包规范一致。

  • declare_section

包含包规范中声明的游标和子程序的定义,对应的子程序的声明和定义的头部除空白外,必须完全匹配。

在包体中还可以声明并定义只能被包内引用的私有对象。

此处不能出现PRAGMA AUTONOMOUS_TRANSACTION.

  • initialize_section

初始化变量,以及一些一次性设置的步骤。

更新包或包体

ALTER PACKAGE语句显示地重新编译包规范、包体或两个都重新编译。显示的重新编译消除了运行时的隐式重编译,阻止了相关运行时的编译错误和性能消耗。

由于包中的所有对象是作为一个单元进行存储的,所以ALTER PACKAGE会对包中的所有对象进行重新编译,不能使用ALTER PROCEDURE或ALTER FUNCTION语句来编译包中的某个存储过程或函数。

此语句不会改变已存在的包的声明或定义,如果想要重新声明或重新定义一个包,需要使用含OR REPLACE子句的CREATE PACKAGE或CREATE PACKAGE BODY语句。

  • COMPILE

重新编译PL/SQL单元,无论它是有效和无效的

首先,如果该单元依赖的任何对象无效,数据库将重新编译它们。数据库还会使依赖于该单元的任何本地对象失效。如果数据库成功重新编译单元,则该单元将变为有效,否则数据库将返回错误,并且该单元标记仍然无效。

在重新编译期间,数据库会丢弃所有持久的编译器开关设置,并从会话中重新检索它们,并在编译后存储它们。要避免此过程,请指定REUSE SETTINGS.

  • DEBUG

具有与PLSQL_OPTIMIZE_LEVEL=1 相同效果,指示PL/SQL编译器生成和存储由PL/SQL调试器使用的代码,仅支持语法。

  • SPECIFICATION

只重新编译包规范,不管包规范有效或无效,在修改包规范后,可以通过重新编译包规范来查看是否有编译错误。

当重新编译一个包规范时,数据库会将所有依赖此包规范的本地对象失效,比如调用包中存储过程或函数的子过程。包体也依赖它的包规范,如果在随后引用这些依赖对象时没有提前重新编译这些依赖对象,则数据库会在运行时,重新编译这些依赖对象。

  • BODY

只重新编译包体,不管包体是否有效。在修改了包体之后,可以通过此语句重新编译包体,重新编译包体不会导致那些依赖包规范的对象失效。

当重新编译包体时,如果包体依赖的对象失效,则数据库首先重新编译包体依赖的失效对象,如果重新编译包体成功,则包体变为有效。

  • PACKAGE

重新编译包规范和包体,不管他们是否有效,重新编译包规范和包体,会导致失效和重新编译依赖此包的对象。

  • REUSE SETTINGS

防止数据库丢弃并重新获取编译器开关设置。使用此子句保留现有设置,并使用它们来重新编译此语句中其他地方未指定值的任何参数,只支持语法。

  • Compiler_parameters_clause

指定PL/SQL的编译参数的值,这些值存储在每个PL/SQL单元的数据字典中,仅支持其语法。

删除包或包体

DROP PACKAGE 语句删除数据库中的一个存储包。这个语句会同时删除包体和包规范。不能使用此语句删除包中的一个单独对象。

  • BODY

只删除包体,如果没有这个子句,则数据库会将包规范和包体都删除。

如果只删除包体,不删除包规范,则数据库不会将依赖包的本地对象失效。

但是在重建包体之前,不能再调用包规范中声明的存储过程或函数。

  • 数据库会失效依赖包规范的本地对象。如果随后引用这些本地对象时,数据库重新编译本地对象,如果被删除的包没有被重建,则返回一个错误。
  • 如果任何统计类型与包关联,则数据库将使用FORCE子句来断开统计数据类型与包的关联,并删除使用统计类型收集的任何用户定义的统计信息。

DISCARD PACKAGE

该功能是为兼容PG的DISCARD功能做的,目前PG支持DISCARD SEQUENCE、DISCARD TEMP、DISCARD PLAN等用来删除当前session的序列、临时表以及计划等缓存,并且DISCARD ALL支持删除本session的PORTAL、临时表、计划、序列等临时存储

支持DISCARD PACKAGE语法,并且在DISCARD ALL中调用函数删除本session的PACKAGE缓存。

示例

1. 创建并查看包规范

create package pkg is

var1 integer;

function test_f(id integer) return integer;

end;

/

create or replace package body pkg is

function test_f(id integer) return integer is

begin

return id+5;

end;

begin

end;

/

2.查看包规范

\dk pkg

3.调用函数

select pkg.test_f(100) from dual;

4.替换包体内容

create or replace package body pkg is

function test_f(id integer) return integer is

begin

return id+15;

end;

begin

end;

/

5.调用函数

select pkg.test_f(100) from dual;

6.删除包

drop package pkg;

7.释放资源

discard package;