我刚刚通过分析一些遗留代码开始了我对Oracle和PL/SQL的冒险.
我遇到了以下声明似乎没有任何定义(BODY)
CREATE OR REPLACE TYPE "TY_STRING_T";
Run Code Online (Sandbox Code Playgroud)
但是在许多包装的许多地方使用.比如这样.
otc ty_string_t := ty_string_t();
Run Code Online (Sandbox Code Playgroud)
我知道这就像创建一个类的实例ty_string_t.
然后它用作例如集合.
otc.EXTEND;
otc(1) := 'test';
Run Code Online (Sandbox Code Playgroud)
为什么这种类型的使用完全没有定义呢?我错过了什么?在类型下的SQL Developer中,当我扩展节点时,没有正文部分.
编辑:
在all_dependencies表中搜索依赖项会得到以下结果.
SELECT * FROM all_dependencies WHERE name = `TY_STRING_T`;
------------------------------------------------------------------------------------------------------------------------------
| OWNER | NAME | TYPE | REFERENCED_OWNER | REFERENCED_NAME | REFERENCED_TYPE | REFERENCED_LINK_NAME | DEPENDENCY_TYPE |
------------------------------------------------------------------------------------------------------------------------------
| AAA | TY_STRING_T | TYPE | SYS | STANDARD | PACKAGE | (null) | HARD |
------------------------------------------------------------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
您出示的声明:
CREATE OR REPLACE TYPE "TY_STRING_T";
Run Code Online (Sandbox Code Playgroud)
创建一个不完整的对象类型:
使用 CREATE TYPE 语句创建对象类型、SQLJ 对象类型、命名变化数组 ( varray )、嵌套表类型或不完整对象类型的规范。
...
不完整类型是由前向类型定义创建的类型。它被称为“不完整”,因为它有名称但没有属性或方法。它可以被其他类型引用,因此可以用于定义相互引用的类型。但是,您必须先完全指定类型,然后才能使用它来创建表或对象列或嵌套表类型的列。
对象关系开发人员指南提供了有关不完整类型和使用它们的示例的更多信息。
但这不是你所拥有的。您正在实例化并填充变量,而不是对象类型。它不会编译具有不完整类型的 PL/SQL 代码- 您会收到PLS-00311: the declaration of "TY_STRING_T" is incomplete or malformed编译错误。
从注释来看,您没有覆盖 PL/SQL 类型,并且(从聊天中)该all_dependencies视图确认您的包依赖于 SQL 级别类型。但它不能按照你想象的方式定义。
您可以使用以下命令检查类型的当前实际定义
select dbms_metadata.get_ddl('TYPE', 'TY_STRING_T') from dual;
Run Code Online (Sandbox Code Playgroud)
通过您所展示的声明,返回:
DBMS_METADATA.GET_DDL('TYPE','TY_STRING_T')
--------------------------------------------------------------------------------
CREATE OR REPLACE TYPE "STACKOVERFLOW"."TY_STRING_T" ;
Run Code Online (Sandbox Code Playgroud)
再次从聊天中,当你运行时,你真的会看到:
CREATE OR REPLACE TYPE "AAA"."TY_STRING_T" as table of varchar2(32767);
Run Code Online (Sandbox Code Playgroud)
这更有意义。不过,Oracle 本身不会添加该as table...部分 - 因为它很乐意将其保留为不完整的对象类型;你只是无法使用它,当然不能像它是一个 varray 一样。
因此,代码库的其他部分使用新的完整定义重新创建了类型;或者有人手动重新创建了该类型(在创建引用它的包之前)。如果我不得不推测,我认为这可能是一个源代码控制问题 - 签入和交付了不完整的代码,并且必须在安装时在每个环境中即时纠正。或者可能是代码在安装后已更改为不再正确的版本。
类型名称表明它始终应该是一个字符串表,而不是一个对象类型;您发现的 create 命令的截断版本永远不会真正创建 varray。
你的理解中并没有真正遗漏任何东西,只是你所看到的并不反映现实。