翻译:陈拓 chentuo@ms.xab.ac
2006 年 6 月16 日
更多包的概念
Copyright © Oracle Corporation, 2001. All rights reserved.
进度表: 时间 主题
40 分钟 讲演
25 分钟 练习
65 分钟 总共
目标
完成本课程后, 您应当能够:
• 用重载特性写包
• 说明子程序相互引用的规则
• 用单次执行 (one­time­only) 过程初始化变量
• 确定持久状态
6­2 Copyright © Oracle Corporation, 2001. All rights reserved.
本课目标
本课介绍更多的PL/SQL高级特性,包括覆盖、前向引用、单次执行过程和变量、 常量、表达式和游标的持久性。你还将学习怎样创建和使用包。还要看看用在SQL语 句中的包函数的作用。
重载 (Overloading)
• 使你能够对在 PL/SQL 块、子程序或包中的不同的子
程序使用的相同的名字
• 要求子程序形式参数的个数、顺序或数据类型不同
• 使得你可以更灵活地构建应用程序。因为重载使用户或 应用程序不被形式参数指定的数据类型或个数所限制
注:本地或打包的子程序可以被重载。单独的子程序不
能重载。
6­3 Copyright © Oracle Corporation, 2001. All rights reserved.oracle decimal类型
重载
重载特性使你能够用相同的名字定义不同的子程序。你可以用用名字和参数区别这 些子程序。有时在两个子程序中的过程是相同的,但传递给它们的变量的参数不同。在 这种情况下,只是逻辑上给它们以相同的名字。PL/SQL 靠检查其形式参数确定哪一个 子程序被调用。只有本地或打包的子程序可以被重载。独立的子程序不能被重载。
限制
下面的情况不能重载:
§两个子程序如果它们的形式参数只是数据类型不同,并且不同的数据类型具有 相同的大类 (NUMBER 和 DECIMAL 就属于相同的大类)。
§两个子程序如果它们的形式参数只是子类不同,并且不同的子类是基于相同的 大类的 (V ARCHAR 和 STRING 是 VARCHAR2 的 PL/SQL 子类)。
§两个函数只是返回类型不同,即使类型是不同的大类,在重载子程序时也会发 生运行时错误。
注:如果参数名也相同上面的限制仍适用。如果你用不同名的参数,那么你可以使用这 些参数的名字符号来调用子程序。
解析调用
编译器尝试到一个匹配调用的声明,它首先查当前的范围,然后,如果需要, 在紧接的封装范围查。如果一个或多个子程序声明 的名字与被调用子程序的名字匹 配,编译器停止搜索。对于在同一个范围级别的同名子程序,编译器需要对实际参数和 形式参数的数目、顺序和数据类型进行匹配。
重载:例
over_pack.sql
CREATE OR REPLACE PACKAGE over_pack
IS
PROCEDURE add_dept
(p_deptno IN departments.department_id%TYPE,
p_name IN departments.department_name%TYPE
DEFAULT ’unknown’,
p_loc IN departments.location_id%TYPE DEFAULT 0); PROCEDURE add_dept
(p_name IN departments.department_name%TYPE
DEFAULT ’unknown’,
p_loc IN departments.location_id%TYPE DEFAULT 0); END over_pack;
/
Package created
6­4 Copyright © Oracle Corporation, 2001. All rights reserved.
重载:例
幻灯片中显示了带重载过程的包的包声明。
这个包中包含了作为两个被重载过程的名字ADD_DEPT 。第一个定义取得3个参 数插入一个新的部门到部门表中。第二个定义只取得2个参数,因为部门ID通过序列 组装。
6­5 Copyright © Oracle Corporation, 2001. All rights reserved.
重载:例
over_pack_body.sql
CREATE OR REPLACE PACKAGE BODY over_pack IS PROCEDURE add_dept (p_deptno IN departments.department_id%TYPE, p_name IN departments.department_name%TYPE DEFAULT ’unknown’, p_loc IN departments.location_id%TYPE DEFAULT 0) IS BEGIN INSERT INTO departme
nts (department_id, department_name, location_id) VALUES (p_deptno, p_name, p_loc); END add_dept; PROCEDURE add_dept (p_name IN departments.department_name%TYPE DEFAULT ’unknown’, p_loc IN departments.location_id%TYPE DEFAULT 0) IS BEGIN INSERT INTO departments (department_id,
department_name, location_id) VALUES (departments_seq.NEXTVAL, p_name, p_loc); END add_dept; END over_pack;
/
重载:例 (续)
如果你用一个显式提供的部门 ID 调用 ADD_DEP ,PL/SQL 使用第一个过程版 本。如果你调用 ADD_DEPT 时没有带部门 ID ,PL/SQL 使用第二个版本。
EXECUTE over_pack.add_dept (980,’Education’,2500) EXECUTE over_pack.add_dept (’Training’, 2400)
SELECT * FROM departments
WHERE department_id = 980;
SELECT * FROM departments
WHERE department_name = ’Training’;

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。