PL/SQL对象依赖关系
功能描述
Vastbase在Oracle兼容模式下,支持PL/SQL与数据库对象(PL/SQL对象)之间互不依赖,主要体现在无论何种方式的依赖,replace、drop、alter引用对象都不会造成依赖对象的级联删除。
依赖关系是指一个对象引用另外一个对象作为其定义的一部分,则就称这两个对象之间有依赖关系。例如,一个存储过程的定义中可能包含一个函数,则称存储过程为依赖对象,函数为引用对象。
PL/SQL对象主要包括:函数、存储过程、包(包函数、包自定义类型)、匿名块、子程序等。数据库对象主要包括除PL/SQL对象以外的表、视图、类型等。
依赖关系说明
引用对象和依赖对象的依赖关系被分为弱依赖和强依赖,可通过查看vb_dependencies.dependedtype字段进行判断,取值为hard表示强依赖,weak表示弱依赖。
若引用对象与依赖对象之间的依赖关系为强依赖,则无论用户对引用对象如何操作(REPLACE、DROP、ALTER、CREATE):
若依赖对象所引用的对象存在,使用ALTER命令对被引用对象进行显式重新编译,编译成功后,对象状态切换为有效状态。
若依赖对象所引用的对象不存在,当用户重新创建好引用对象,并使用ALTER命令对引用对象进行显式重新编译,编译成功后,对象状态切换为有效状态。
若引用对象与依赖对象之间的依赖关系为弱依赖,则无论用户对引用对象如何操作(REPLACE、DROP、ALTER、CREATE):
若依赖对象所引用的对象存在,则PL/SQL内部会进行自动隐式编译。
若依赖对象所引用的对象不存在,当用户重新创建好引用对象后,PL/SQL内部会进行自动隐式编译。
显式重新编译
通过使用ALTER…COMPILE命令对PL/SQL对象重新编译。
注意事项
该功能仅在数据库兼容模式为Oracle时支持(即数据库实例初始化时指定DBCOMPATIBILITY='A')。
PL/SQL暂不支持view%rowtype。
当函数的参数类型为用户自定义的table/varry类型、或为package自定义类型时,函数重载时必须根据参数类型名进行重载。
集合类型不能将其转换为基类型数组去处理。
函数调用传参时,必须使用函数参数类型定义的变量去传参。
示例
示例1: PL/SQL内部进行隐式重新编译。
1、创建引用对象table类型。
CREATE TYPE tabletype1_1171532 is table of int;
2、创建依赖对象函数。
create or replace type tabletype_1171532 as object (
col1 int,
col2 int,
MEMBER FUNCTION tabletype_fun_1171532() return int
);
3、创建对象类型body。
create or replace type body tabletype_1171532 as
MEMBER FUNCTION tabletype_fun_1171532() return int
as
var1 tabletype1_1171532 := tabletype1_1171532(1,2,3,4,5);
begin
raise info 'package public function variable ref table: var1[%]',var1;
return 1;
end;
end;
/
4、调用函数。
declare
obj_var tabletype_1171532;
begin
raise info '%', obj_var.tabletype_fun_1171532();
end;
/
返回结果为如下:
INFO: package public function variable ref table: var1[{1,2,3,4,5}]
CONTEXT: PL/pgSQL function inline_code_block line 3 at RAISE
INFO: 1
5、删除引用对象类型,并查看依赖关系的类别。
drop type tabletype1_1171532;
\dT+ tabletype1_1171532
select schemaname,objectname,objecttype,refname,refschemaname,refpackagename,refobjectname,refobjectsubname,refobjecttype,dependedtype from vb_dependencies where objectname='tabletype_1171532';
返回结果为如下,成功删除对象类型,且从视图查看依赖关系的类别可知引用对象与被引用对象之间为弱依赖:
List of data types
Schema | Name | Internal name | Size | Elements | Access privileges | Description
--------+------+---------------+------+----------+-------------------+-------------
(0 rows)
schemaname | objectname | objecttype | refname | refschemaname | refpackagename | refobjectname | refobjec
tsubname | refobjecttype | dependedtype
------------+-------------------+------------+---------------------+---------------+----------------+--------------------+---------
---------+---------------+--------------
public | tabletype_1171532 | type body | tabletype1_1171532 | public | | tabletype1_1171532 |
| type | weak
public | tabletype_1171532 | type body | tabletype1_1171532 | public | | tabletype1_1171532 |
| type | weak
(2 rows)
6、调用函数,此时提示引用对象不存在。
declare
obj_var tabletype_1171532;
begin
raise info '%', obj_var.tabletype_fun_1171532();
end;
/
返回结果为如下:
ERROR: type "tabletype1_1171532" does not exist
LINE 1: DECLARE var1 tabletype1_1171532 := tabletype1_1171532(1,2,3...
^
QUERY: DECLARE var1 tabletype1_1171532 := tabletype1_1171532(1,2,3,4,5);
begin
raise info 'package public function variable ref table: var1[%]',var1;
return 1;
end
CONTEXT: compilation of PL/pgSQL function "tabletype_fun_1171532" near line 1
PL/pgSQL function inline_code_block line 3 at RAISE
7、重新创建table类型,可恢复引用对象。
CREATE TYPE tabletype1_1171532 is table of int;
8、再次调用时可成功调用:
declare
obj_var tabletype_1171532;
begin
raise info '%', obj_var.tabletype_fun_1171532();
end;
/
返回结果为如下:
INFO: package public function variable ref table: var1[{1,2,3,4,5}]
CONTEXT: PL/pgSQL function inline_code_block line 3 at RAISE
INFO: 1
示例2: PL/SQL对象引用PL/SQL对象,依赖对象为函数,引用对象为自定义类型,进行显式重新编译。
1、创建引用对象。
create or replace package pkg1_1171636 as
type v1 is varray(10) of varchar2(20);
end pkg1_1171636;
/
2、创建依赖对象。
create or replace function depend_func_1_1171636(arg1 pkg1_1171636.v1) return pkg1_1171636.v1
as
begin
arg1[1] := 'clouds';
arg1[2] := 'break';
return arg1;
end;
/
3、执行依赖对象,调用函数。
declare
var1 pkg1_1171636.v1;
begin
var1 := depend_func_1_1171636(var1);
raise info 'var1:%',var1;
end;
/
返回结果为如下,表示成功调用函数:
INFO: var1:{clouds,break}
ANONYMOUS BLOCK EXECUTE
4、删除引用对象。
drop package pkg1_1171636;
5、调用依赖对象,此时提示引用对象不存在。
declare
var1 pkg1_1171636.v1;
begin
var1 := depend_func_1_1171636(var1);
raise info 'var1:%',var1;
end;
/
返回结果为如下,此时由于步骤4,导致提示引用对象不存在:
ERROR: type "pkg1_1171636.v1" does not exist
LINE 1: DECLARE var1 pkg1_1171636.v1;
^
QUERY: DECLARE var1 pkg1_1171636.v1;
begin
var1 := depend_func_1_1171636(var1);
raise info 'var1:%',var1;
end
6、重建引用对象,并显式重新编译依赖对象。
create or replace package pkg1_1171636 as
type v1 is varray(10) of varchar2(20);
end pkg1_1171636;
/
alter function depend_func_1_1171636(arg1 pkg1_1171636.v1) compile;
7、调用依赖对象,可成功调用。
declare
var1 pkg1_1171636.v1;
begin
var1 := depend_func_1_1171636(var1);
raise info 'var1:%',var1;
end;
/
返回结果为如下,表示成功调用函数:
INFO: var1:{clouds,break}
ANONYMOUS BLOCK EXECUTE