引用包

在包头中声明的对象可以在包外调用,可以从数据触发器、存储子程序、应用程序和各种工具中引用包中的内容。调用的方法和调用单独的过程或函数的方法基本相同,唯一的区别就是要在调用的过程或函数名前加上包的名字(中间用“.”分隔)。

语法:

Package_name.Item_Name -- 全局变量、常量
Package_name.Subprogram_name -- 全局函数、过程
Package_name.Exception_name -- 全局异常

说明:

在包体内,包头中的变量可以直接引用,即可以不用包名为其前缀。当然,也可以使用全名(包名为前缀)进行引用。但是若调用包中的过程和函数,不论公有和私有必须使用包名为前缀,若不加前缀则认为是包外的过程或函数。

使用包中全局变量时的注意事项,执行如下用例

示例1:使用包中变量

--  清理环境
DROP PACKAGE pack;
DROP TABLE tab CASCADE;

create table tab
(
    a char,
    b int
);

create or replace package pack as
    g_var tab.a%TYPE := 'a';
    procedure proc;
end;
/

create or replace package body pack as
    procedure proc as
    begin
        dbms_output.put_line(g_var);
    end proc;
end;

/
exec pack.proc;

--删除表重新创建新的表,a的类型变为int
drop table tab;
create table tab
(
    a int,
    b int
);
exec pack.proc;
ERROR, 错误的数值格式 'a'



--删除包
DROP PACKAGE pack;
DROP TABLE tab CASCADE;

应该执行中报错的,这里可以正确执行,与预期不符。

包中全局变量因为类型或者默认值的依赖发生改变进而需要改变的,数据库可能发生不可预知的情况,建议包中全局变量使用constant定义,类型依赖发生变化时,如果发生异常情况使用alter package package_name compile操作可以使包正常使用。

可以在存储过程,函数中引用包中的全局变量、自定义类型。每个会话会有一个包实例,各个会话间的全局变量不会互相影响。使用在包外的过程中引用包中的全局变量时,要使用变量的全名,即包名.变量名,自定义类型也一样。

示例2:使用包中全局变量

--清理环境
DROP PROCEDURE proc;
DROP PACKAGE pack;

create or replace package pack is
    g_var integer;
    function f return integer;
end;
/

create or replace package body pack is
    function f return integer is
    begin
        return g_var;
    end;
begin
    g_var = 1;
end;
/

CREATE OR REPLACE PROCEDURE proc AS
declare
    a integer := pack.g_var;
begin
    a = a + pack.g_var;
    dbms_output.put_line('a: ' || a);
    pack.g_var = pack.g_var + 1;
    dbms_output.put_line('pack.g_var: ' || pack.g_var);
end;

/
EXEC proc;
a: 2
pack.g_var: 2

--删除
DROP PROCEDURE proc;
DROP PACKAGE pack;

可以在过程中使用包中定义的类型,支持自定义类型作为包中函数的输入输出参数,返回值。目前还不支持自定义类型作包外函数的输入输出参数和返回值。目前自定义类型支持最大嵌套10层。

示例3:使用包中自定义类型

--  清理环境
DROP PROCEDURE proc;
DROP PACKAGE pack;

create or replace package pack is
    type rec_type is record 
        (
            a int, 
            b int
        );
    type nt_type is table of rec_type index by pls_integer;
    function func(nt nt_type, i integer) return rec_type;
end;
/

create or replace package body pack is
    function func(nt nt_type, i integer) return rec_type is
    begin
        return nt(i);
    end;
end;
/
--包外过程的参数返回值还不支持使用包中自定义类型
create or replace procedure proc is
    --过程内部可以使用
    rec pack.nt_type;
begin
    rec(1).a := 1;
    rec(1).b := 2;
    rec(2).a := 3;
    rec(2).b := 4;
    dbms_output.put_line(pack.func(rec, 2).a);

end;
/
exec proc;
--删除包
DROP PROCEDURE proc;
DROP PACKAGE pack;