Oracle SQL 学习笔记22 - 包
2020-02-09 本文已影响0人
赵阳_c149
package的构成
PL/SQL package 概要
Package是PL/SQL的重要特性,它将逻辑上相关的组件组合在一起,包括PL/SQL类型,Variable,数据结构,异常,存储结构和函数。有了package,Oracle可以一次将package定义的多个对象读入内存。
package 定义的结构
package的定义包含两部分:
- Specification:Public
-
Body:private
pac_stru.JPG
Package 组件的可视性
开发 PL/SQL Packages
创建package specification 和 package body
创建Package说明部分
- 语法
CREATE [OR REPLACE] PACKAGE package_name IS|AS
public type and variable declarations
subprogram specifications
END [package_name];
其中,OR REPLACE
选项用于替换已经存在的package。定义于package specification 的变量默认被初始化为NULL。而定于于package specification 的常量对于所有对package有执行权限的用户来说,都是可见的。
- 举例
CREATE OR REPLACE PACKAGE comm_pkg IS
std_comm NUMBER := 0.10; --initialized to 0.10
PROCEDURE reset_comm(new_comm NUMBER);
END comm_pkg;
创建Package Body
- 语法
CREATE [OR REPLACE] PACKAGE BODY package_name IS|AS
private type and variable declarations
subprogram bodies
[BEGIN initialization statements]
END [package name];
定义于package body变量都是是私有的,在package body之外不可见。任何私有结构必须先定义后引用。公有结构对package body是可见的。
- 举例
CREATE OR REPLACE PACKAGE BODY comm_pkg IS
FUNCTION validate(comm NUMBER) RETURN BOOLEAN IS
max_comm employees.commission_pct%TYPE;
BEGIN
SELECT MAX(commission_pct) INTO max_comm
FROM employees;
RETURN (comm BETWEEN 0.0 AND max_comm);
END validate
PROCEDURE reset_comm(new_comm NUMBER) IS
BEGIN
IF validate(new_comm) THEN
std_comm := new_comm ; -- reset public var
ELSE RAISE_APPLICATION_ERROR(-20120, 'Bad Commission');
END IF;
END reset_comm;
END comm_pkg;
package的使用
调用package子程序
CREATE OR REPLACE BODY comm_pkg IS...
PROCEDURE reset_comm(new_comm NUMBER) IS
BEGIN
IF validate(new_comm) THEN
std_comm := new_comm;
ELSE...
END IF
END reset_comm;
END comm_pkg;
EXECUTE comm_pkg.reset_comm(0.15)
EXECUTE scott.comm_pkg.reset_comm(0.15)
创建和使用无包体Package
CREATE OF REPLACE PACKAGE global_consts IS
mile_2_kilo CONSTANT NUMBER := 1.6093;
kilo_2_milo CONSTANT NUMBER := 0.6214;
yard_2_meter CONSTANT NUMBER := 0.9144;
meter_2_yard CONSTANT NUMBER := 1.0936;
END global_consts;
BEGIN
DBMS_OUTPUT.PUT_LINE('20 miles = ' || 20
* global_consts.mile_2_kilo || ' km');
END
CREATE FUNCTION mtr2yrd(m NUMBER) RETURN IS
BEGIN
RETURN (m * global_consts.meter_2_yard);
END mtr2yrd;
/
EXECUTE DBMS_OUTPUT.PUT_LINE(mtr2yrd(1));
删除Package
- 删除包和体
DROP PACKAGE package_name;
- 仅仅删除包体
DROP PACKAGE BODY package_name;
在数据字典中查看包的信息
SELECT text
FROM user_source
WHERE name = 'COMM_PKG' AND type = 'PACKAGE';
SELECT text
FROM user_source
WHERE name = 'COMM_PKG' AND type = 'PACKAGE BODY';
创建包的一般规则
- 立足于将来反复重用来构建package
- 先定义 package specification,后定义 package body
- 仅在 package specification中定义公有结构
- 若需要在一个session的多个事务中用到,则可以将其置于 package body的声明部分
- 对 package specification 的改变需要重新编译相关引用对象
- 尽可能少的在 package specification 进行定义
使用package的优势
- 模块化:封装了相关结构
- 易于维护:将逻辑上相关的功能放到了一起
- 便于程序设计:specification和body部分可以分别编码和编译
- 隐藏信息:
- 只有在 package specification中声明过的才对其他应用是可见的和可访问的
- 在body内的私有结构被隐藏和不可见的
- body中所有的代码都被隐藏
- 增强功能:变量和cursor定义的持久化
- 提高性能:
- 当一次被调用的时候,整个package装入内存
- 所有用户调用同一个pacakge只占用一块内存
- 程序依赖结构简化了
- 重载:多个子程序可以使用同一个名称