包是由2个主要的部分构成的:
  • 包定义:这是一个公有接口,(公有成员可以在包的外部引用)。我们在包定义中声明所有包含在包中数据库对象。
  • 包主体:包含包定义内部声明的所有数据库对象的具体应用实现。

包主体的内容是包定义中的所有对象具体定义实现,包括对成员定义的具体实现和对外部程序不可见的私有成员声明信息。所以,我们可以调试,增强或替代一个包主体,而无需改变包的定义。类似的,我们能够改变包主体而无需重新编译调用包的程序,因为对于这些程序来说,具体的实现信息是不可见的。

包定义语法

包的定义给包(API)定义了用户接口。定义中列出了包用户可见的函数、存储过程、类型、异常及游标。

用于定义包接口的语法如下:
CREATE [ OR REPLACE ] PACKAGE package_name
  [ authorization_clause ]
  { IS | AS }
  [ declaration; ] ...
  [ procedure_or_function_declaration; ] ...
END [ package_name ] ;
其中 authorization clause : =
{ AUTHID DEFINER } | { AUTHID CURRENT_USER }
其中 procedure or function declaration :=
procedure declaration | function declaration
其中procedure declaration :=
PROCEDURE proc name[ argument list ] [restriction pragma];
其中function_declaration :=
FUNCTION func_name [ argument_list ]

RETURN rettype [ restriction pragma ];
				
其中argument_list :=
( argument declaration [, ...] )
其中argument declaration :=
argname [ IN | IN OUT | OUT ] argtype [ DEFAULT value ]
其中restriction pragma : =
PRAGMA RESTRICT_REFERENCES(name, restrictions)
其中restrictions :=
restriction [, ... ]

参数

参数 参数说明
package name package_name是分配给包的标识符,且每个包在模式中必须要有一个独一无二的名称。
AUTHID DEFINER 如果忽略了AUTHID子句或者指定了DEFINER子句,那么使用包所有者的权限和搜索路径来分别确认是否有访问数据库对象的权限,和解析非限定数据库对象的引用。
AUTHID CURRENT_USER 如果指定了CURRENT_USER,那么使用当前执行包中程序用户的权限和搜索路径来确认访问数据库对象的权限,和解析对非限定数据库对象的引用。
declaration declaration是公有变量的标识符。通过使用package_name.variable这种语法形式,我们可以从包的外部访问公有变量。可以没有一个或多个公有变量,也可以没有公有变量。在存储过程或函数的声明前,必须进行公有变量的定义。declaration能够使用下面任意一种的类型。
  • 变量声明
  • 记录声明
  • 集合声明
  • ref cursor 和 Cursor 变量声明
  • 记录,集合和REF CURSORS的类型定义
  • 异常
  • 对象变量声明
argname 参数的名称。在函数中或存储过程体中被这个参数名称所引用的参数。
IN | IN OUT | OUT 参数模式。
  • IN仅用于声明输入的参数。这是一个缺省模式。
  • in out可允许参数接收一个值,也可以返回一个值。
  • out仅用于指定输出的参数。
argtype

参数的数据类型。一个参数类型可以是一个基础数据类型、一个使用%type的已有的列类型的副本或是一个用户定义的类型,例如嵌套表或对象类型。我们不能指定任何基础类型的长度,例如,可以指定varchar2,但不能指定varchar2 (10)

通过编写tablename. columnname%TYPE引用列类型。使用tablename. columnname%TYPE有时候可以使存储过程独立于表定义的变化。

DEFAULT value 如果在调用过程中没有为输入参数提供缺省值,那么default子句将会为输入参数提供一个值。然而在模式in out out下,default子句将不能为参数指定缺省值。
name name 是函数或存储过程的名称。
restriction 下列关键字可被用于兼容模式或被忽略:
  • RNDS
  • rnps
  • TRUST
  • WNDS
  • WNPS

包主体定义语法

包执行细节所属于包主体中。包主体可能会含有包的使用者不可见的对象。POLARDB for Oracle支持下列包主体的语法:
CREATE [ OR REPLACE ] PACKAGE BODY package_name
  { IS | AS }
  [ private_declaration; ] ...
  [ procedure_or_function_definition; ] ...
  [ package_initializer ]
END [ package_name ] ;
其中 procedure or function definition :=
procedure definition | function definition
其中 procedure definition :=
PROCEDURE proc name[ argument list ] [ options list ] { IS | AS }

procedure body END [ proc name ] ;
				
其中 procedure_body :=
[ declaration; ] [, ... ] BEGIN

statement; [... ] [ EXCEPTION

{ WHEN exception [OR exception] [...]] THEN statement; } [...]

]
				
其中 function definition :=
FUNCTION func_name [ argument_list ] RETURN rettype [DETERMINISTIC] [ options list ] { IS | AS }

function body END [ func name ] ;
				
其中 function_body :=
[ declaration; ] [, ... ] BEGIN

statement; [... ]

[ EXCEPTION

{ WHEN exception [ OR exception ] [... ] THEN statement; } [...]

]
				
其中 argument_list :=
( argument declaration [, ...] )
其中 argument declaration :=
argname [ IN | IN OUT | OUT ] argtype [ DEFAULT value ]
其中 options_list :=
option [ ... ]
其中 option :=
COST execution cost ROWS result rows

SET config_param { TO value | = value | FROM CURRENT } 
				
其中 package initializer :=
BEGIN

statement; [... ] END;
				

参数

参数 参数说明
package name package_name是包主体的名称。前提是必须已有这个名称的包定义。
private declaration private_declaration是一个私有变量的标识符,这个私有变量可以被包内部的存储过程或者函数访问。在包的内部可以不声明私有变量,或者声明一个或多个私有有变量。private_declaration可以有以下几种形式:
  • 变量声明
  • 记录声明
  • 集合声明
  • ref cursor和Cursor变量声明
  • 记录,集合和REF CURSORS的类型定义
  • 异常
  • 对象变量声明
proc name 所要创建的存储过程的名称。
Declaration 变量、类型或ref cursor的声明。
statement SPL 程序语句。需要注意的是,declare - begin - end 代码块本身是SPL 语句。因此,函数体会包含嵌套表。
exception 异常条件名称。例如,no_data_found、others等。
func name 所要创建的函数名称。
rettype 返回的数据类型可以是argtype 列出的任何一种数据类型。至于argtype,不能为rettype指定长度。
DETERMINISTIC 使用deterministic 指定函数在指定相同参数值时返回的总是相同结果。deterministic函数不能用于修改数据库。
说明 deterministic关键字相当于PostgreSQL中 IMMUTABLE选项。
declaration 变量、类型或ref cursor的声明。
argname 形参的名称。这个参数在存储过程体中以这个名称引用。
IN | IN OUT | OUT 参数模式。
  • IN:仅用于声明输入的参数。这是一个缺省模式。
  • in out:可允许参数接收一个值,也可以返回一个值。
  • out:仅用于指定输出的参数。
argtype

参数的数据类型。一个参数类型可以是一个基础数据类型、一个使用%type的已有的列类型的副本或是一个用户定义的类型,例如嵌套表或对象类型。我们不能指定任何基础类型的长度,例如,可以指定varchar2,但不能指定varchar2(10)

通过编写tablename.columnname%TYPE引用列类型。使用tablename.columnname%TYPE有时候可以使存储过程独立于表定义的变化。

DEFAULT value 如果在调用存储过程中没有为输入参数提供缺省值,那么default子句将会为输入参数提供一个值。然而在模式in out out下,default子句不能为参数指定缺省值。
说明 下列选项不与Oracle兼容。它们仅是POLARDB for Oracle提供的Oracle包语法的扩展。
STRICT 如果用null 参数调用函数时,strict关键字用于指定函数不会被执行。取而代之的是,函数将会返回null
LEAKPROOF leakproof关键字用于指定函数不显示任何关于参数的信息,而不是通过返回的值来指定。
execution cost execution_cost用于指定一个正数,这个正数为在cpu_operator_cost单元中的函数提供预估执行。如果函数返回的是一个集,那么这就是所返回的每个记录的成本。缺省为0.0025。
result rows result_rows是查询计划器估计函数会返回的记录数量。缺省为1000。
SET 使用set子句来为函数的持续时间指定一个参数值。
  • config_param用于指定参数名称。
  • value用于指定参数值。
  • from current用于保证在函数结束时参数值会被重新存储。
package initializer 当包第一次被引用时,package_initializer中的语句将被执行一次每个用户的会话。
说明 strict、leakproof、cost、rows和set关键字是为POLARDB for Oracle提供扩展的函数性,并不被Oracle支持。