创建程序包
一个包对象结构包括:包规范(包头)与包体。
包头定义了包对象所有的公有元素信息,可包括游标、数据类型、存储过程/函数等元素。
包体是对包头定义的具体实现,在包体内定义公有存储过程或存储函数的执行体。同时包体内还可以声明包的私有元素,声明的游标、变量、用户类型等在包头内未定义,则这些对象为私有对象,用户不可通过包进行访问,但可在包体内进行调用。
包头定义
语法格式
sql
packdecl::=
CREATE [FORCE | OR REPLACE | OR REPLACE FORCE] PACKAGE name_space
[AUTHID {DEFAULT | DEFINER | CURRENT_USER | USER}]
[COMMENT SCONST]
{IS | AS} PackSpecItem [PackSpecItem]...
END [name_space]
PackSpecItem::=
VarDef ;
| ProcDecl ;
参数说明
- 创建选项:
FORCE
:强制创建包,即使存在依赖对象无效。OR REPLACE
:替换现有包(若存在)。OR REPLACE FORCE
:组合使用,允许替换并强制创建。
- 包名称(
name_space
):- 格式:
[schema_name.]package_name
(可能包含模式名)。
- 格式:
- 权限控制(
AUTHID
):DEFAULT
:默认权限。DEFINER
:使用定义者的权限执行。CURRENT_USER | USER
:使用调用者的权限执行。
- 注释(
COMMENT
):- 可选,后接字符串字面量(如
'This is a package'
)。
- 可选,后接字符串字面量(如
- 包体声明:
IS
或AS
关键字引导包规范体。- 包含一个或多个
PackSpecItem
(变量或过程声明),每个项以分号;
结尾。
- 结束标记:
END
关键字后可选跟包名(需与开头的name_space
一致)。
- 变量定义(
VarDef
):- 示例:
var_name datatype [NOT NULL] [:= default_value];
- 需符合变量声明语法规则(如类型、约束、默认值)。
- 示例:
- 过程声明(
ProcDecl
):- 示例:
PROCEDURE proc_name (param_list) [RETURN datatype];
- 包含过程名、参数列表、返回类型(可选)。
- 示例:
说明:
在包头定义中,针对存储过程与函数的定义可通过重载的方式实现不同输入参数的同名过程/函数声明。
包体创建
语法格式
sql
PackBody::=
CREATE [FORCE | OR REPLACE | OR REPLACE FORCE] PACKAGE BODY name_space
{IS | AS}
[DECLARE VarDefList]
PackMemberProcs
[BEGIN pl_stmt_list]
EXCEPTION Exception_Item [Exception_Item]...
END [name_space]
VarDefList::=
VarDef ;
| VarDefList VarDef ;
PackMemberProcs::=
ProcDef ;
| PackMemberProcs ProcDef ;
参数说明
- 创建选项:
FORCE
:强制创建包体,忽略依赖对象状态。OR REPLACE
:替换现有包体(若存在)。OR REPLACE FORCE
:组合使用(需按固定顺序)。
- 包名称(
name_space
):- 格式:
[schema_name.]package_name
(可能包含模式名)。
- 格式:
- 声明部分(
DECLARE VarDefList
):DECLARE
关键字可选(标准 PL/SQL 包体中通常省略,变量直接定义在IS|AS
后)。
- 变量定义列表(
VarDefList
):- 每个VarDef为变量声明(如
counter NUMBER := 0;
)。 - 分号
;
分隔多个变量定义。
- 每个VarDef为变量声明(如
- 成员过程(
PackMemberProcs
):- 包含一个或多个过程/函数定义(
ProcDef
),每个以分号;
结尾。
- 包含一个或多个过程/函数定义(
- 初始化块(
BEGIN pl_stmt_list
):- 可选,用于执行包初始化逻辑(如赋值、调用过程)。
pl_stmt_list
为PL/SQL语句列表(如DBMS_OUTPUT.PUT_LINE('Initialized');
)。
- 异常处理(
EXCEPTION
):- 可选,捕获包级异常。
Exception_Item
格式:WHEN exception_name THEN stmt_list
。
- 结束标记:
END
后可选跟包名(需与开头的name_space
一致)。
- 变量定义列表(
VarDefList
):- 每个VarDef为变量声明(如
counter NUMBER := 0;
)。 - 分号
;
分隔多个变量定义。
- 每个VarDef为变量声明(如
说明:
在包体内声明与定义的对象在包头内若无声明,则对象为私有元素对象,这类元素对象只能在包体内调用,用户无法通过包进行访问使用。
示例
创建一个封装了一个存储过程的pack_test包,存储过程实现了输出USER_TABLES系统表中表名的功能。调用该包可使用命令EXEC pack_test.proc1
。
sql
-- 创建包头:
CREATE OR REPLACE PACKAGE pack_test
AUTHID DEFAULT
COMMENT '输出USER_TABLES系统表中表名'
IS
PROCEDURE proc1();
END;
/
-- 创建包体:
CREATE OR REPLACE PACKAGE body pack_test IS
PROCEDURE proc1() IS
CURSOR mycur IS
SELECT table_name FROM user_tables;
con INTEGER;
name VARCHAR;
BEGIN
SELECT count(*) INTO con FROM user_tables;
OPEN mycur;
FOR i IN 1 .. con LOOP
FETCH mycur
INTO name;
send_msg(name);
END LOOP;
close mycur;
END;
END;
/