创建以下内容时:
create view v (a, b) as select 1, 2 from dual;
create or replace package p as
type t is table of v%rowtype;
function f return t pipelined;
end p;
/
我可以看到字典中出现了一些合成类型:
select o.object_name, s.line, s.text
from all_objects o
join all_source s on o.owner = s.owner and o.object_name = s.name
where o.owner = 'TEST'
and o.object_name like 'SYS_PLSQL_%'
order by 1;
结果:
|OBJECT_NAME |LINE|TEXT |
|--------------------------|----|--------------------------------------------------------------------------------|
|SYS_PLSQL_3473F824_9_1 |1 |type SYS_PLSQL_3473F824_9_1 as table of "TEST"."SYS_PLSQL_56AACD46_15_1";|
|SYS_PLSQL_3473F824_DUMMY_1|1 |type SYS_PLSQL_3473F824_DUMMY_1 as table of number; |
|SYS_PLSQL_56AACD46_15_1 |1 |type SYS_PLSQL_56AACD46_15_1 as object ("A" NUMBER, |
|SYS_PLSQL_56AACD46_15_1 |2 |"B" NUMBER); |
|SYS_PLSQL_56AACD46_DUMMY_1|1 |type SYS_PLSQL_56AACD46_DUMMY_1 as table of number; |
这些都出现在ALL_OBJECTS
中,但只有集合类型也出现在ALL_COLL_TYPES
中。在 ALL_TYPES
中找不到 OBJECT
类型:
select type_name, elem_type_name
from all_coll_types
where owner = 'TEST' and type_name like 'SYS_PLSQL_%'
union all
select type_name, null as elem_type_name
from all_types
where owner = 'TEST' and type_name like 'SYS_PLSQL_%';
结果
|TYPE_NAME |ELEM_TYPE_NAME |
|--------------------------|-----------------------|
|SYS_PLSQL_3473F824_9_1 |SYS_PLSQL_56AACD46_15_1|
|SYS_PLSQL_3473F824_DUMMY_1|NUMBER |
|SYS_PLSQL_56AACD46_DUMMY_1|NUMBER |
这是 ALL_TYPES
定义中的错误,还是有充分理由不列出 SYS_PLSQL_56AACD46_15_1
?毕竟,它出现在其他地方,专门从 SYS_PLSQL_3473F824_9_1
ALL_COLL_TYPES.ELEM_TYPE_NAME
引用
我正在使用 Oracle Database 18c Express Edition 版本 18.0.0.0.0
最佳答案
可能只是因为没有必要。可以从 SQL 间接引用集合类型:
select * from table(p.f);
但是对象类型不能。
如果您仅声明它或仅在过程中使用它,则类型不会出现在 all_objects
中,集合类型也不会出现在 all_coll_types
中:
create or replace package p as
type t is table of v%rowtype;
end p;
/
或
create or replace package p as
type t is table of v%rowtype;
procedure p (v_t in out t);
end p;
/
对于这两个包规范,您的查询返回零行。添加可能从 SQL 上下文调用的公共(public)引用(即返回该类型的函数)后,数据字典需要了解它。
但是您不能直接引用集合的元素类型 - 如果您有一个返回 v%rowtype
的函数,那么它不需要是它自己的合成类型,并且该类型的变量与合成元素类型兼容。
因此 SQL 需要能够处理集合类型,并且需要在 all_coll_types
中查看它才能做到这一点(大概 - 谁知道幕后发生了什么);集合类型和记录类型之间的链接是通过 elem_type_name 实现的。记录类型无法使用,因此不需要在 all_types
中列出 - 正如文档所述,它仅适用于 object 类型,因此记录类型反正不太适合那里。
同样,集合类型一旦声明就会出现在 all_plsql_types
中,即使它没有被使用;但元素(记录)类型永远不会出现在那里,因为它无法被引用。
关于oracle - 在 Oracle 18c 中,合成 TABLE 类型显示在 ALL_COLL_TYPES 中,但 OBJECT 类型不会显示在 ALL_TYPES 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67192859/