oracle - 在 Oracle 18c 中,合成 TABLE 类型显示在 ALL_COLL_TYPES 中,但 OBJECT 类型不会显示在 ALL_TYPES 中

标签 oracle plsql information-schema oracle18c

创建以下内容时:

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 中,即使它没有被使用;但元素(记录)类型永远不会出现在那里,因为它无法被引用。

db<>fiddle

关于oracle - 在 Oracle 18c 中,合成 TABLE 类型显示在 ALL_COLL_TYPES 中,但 OBJECT 类型不会显示在 ALL_TYPES 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67192859/

相关文章:

java - 如何在 Spring Hibernate Oracle DB 中使用 WebLogic 配置的连接池(使用 JNDI 名称)

oracle - 如何在 Oracle 中自动启动监听器

database - 这个数据库设计多对多适合生产吗?

oracle - SQL 命令在包中时跳过 where 子句

sql - 使用可选参数创建过程的方法?

sql - 如何检查哪个函数使用类型?

java - 监听器拒绝连接,并出现以下错误 : ORA-12519, TNS:未找到适当的服务处理程序

sql - 如何编写 PL/SQL 在插入之前先检查记录是否存在

permissions - 如何授予其他人在 BigQuery 中读取我的 INFORMATION_SCHEMA.SCHEMATA 的权限?

SQL - 服务器上所有数据库的 INFORMATION_SCHEMA