在 PL/SQL 块中定义引用其自身集合的记录类型

Pol*_*zny 2 oracle plsql forward-declaration hoisting

如何在 PL/SQL 匿名块中定义包含自身集合属性的记录类型?看下面的例子:

DECLARE
    type t_item is record (
        name varchar2(64),
        children t_items              -- referencing t_items type
    );
    type t_items is table of t_item;  -- referencing t_item type

BEGIN
    -- script code
END
Run Code Online (Sandbox Code Playgroud)

PL/SQL 没有类型提升,因此 Oracle 引擎会引发异常:

PLS-00498:在声明之前非法使用类型

如何定义属性中t_item包含 a 的记录?table of t_itemchildren

MT0*_*MT0 5

您可以通过继承来使用 SQL 作用域中定义的对象:

SQL小提琴

Oracle 11g R2 架构设置

CREATE TYPE abstract_item IS OBJECT (
  name VARCHAR2(64)
) NOT FINAL NOT INSTANTIABLE
/

CREATE TYPE t_items IS TABLE OF abstract_item
/

CREATE TYPE t_item UNDER abstract_item (
  children t_items
) INSTANTIABLE
/
Run Code Online (Sandbox Code Playgroud)

查询1

SELECT t_item(
         '1',
         t_items(
           t_item( '1.1', t_items() ),
           t_item(
             '1.2',
             t_items(
               t_item( '1.2.1', null )
             )
           ),
           t_item( '1.3', null )
         )
       )
FROM   DUAL
Run Code Online (Sandbox Code Playgroud)

结果:(SQLFiddle 没有很好地显示它 - 但它运行时没有错误)

| T_ITEM('1',T_ITEMS(T_ITEM('1.1',T_ITEMS()),T_ITEM('1.2',T_ITEMS(T_ITEM('1.2.1',NULL))),T_ITEM('1.3',NULL))) |
|-------------------------------------------------------------------------------------------------------------|
|                                                                                  oracle.sql.STRUCT@2a094aab |
Run Code Online (Sandbox Code Playgroud)

您可以在 PL/SQL 中使用类似的声明:

DECLARE
  items t_item;
BEGIN
  items = t_item( 'Item Name', t_items( /* ... */ ) );
END;
/
Run Code Online (Sandbox Code Playgroud)