【问题标题】:Nested class (Object Type) in PL/SQLPL/SQL 中的嵌套类(对象类型)
【发布时间】:2018-10-21 16:17:27
【问题描述】:

在 Java 中可以定义递归(嵌套)类,如:

private class Node
{
  Item item;
  Node next;
}

是否可以使用 PL/SQL 对象类型创建类似的结构?

【问题讨论】:

  • 以下答案是否帮助您理解了您的要求。如果它们对您有用,您可以接受任何一个答案以供将来的读者参考。

标签: java oracle oop plsql object-type


【解决方案1】:

您可以使用可替换类型来规避明显的自引用问题,如下所示。

CREATE TYPE item_t
AS 
   OBJECT (
      attr_a VARCHAR2 (30));
/

CREATE TYPE base_node_t
AS
   OBJECT (
      item item_t)
      NOT FINAL 
      NOT INSTANTIABLE;
/

CREATE TYPE node_t
   UNDER base_node_t (
      next_node base_node_t);
/

DECLARE
   nodes node_t := 
      node_t (
         item_t ( 'grandparent'),
         node_t (
            item_t ( 'parent'),
            node_t (
               item_t ( 'child'),
               NULL)));
BEGIN
   DBMS_OUTPUT.put_line (
      XMLTYPE (nodes).getclobval (0, 2));
END;
/

<NODE_T>
  <ITEM>
    <ATTR_A>grandparent</ATTR_A>
  </ITEM>
  <NEXT_NODE>
    <ITEM>
      <ATTR_A>parent</ATTR_A>
    </ITEM>
    <NEXT_NODE>
      <ITEM>
        <ATTR_A>child</ATTR_A>
      </ITEM>
      <NEXT_NODE/>
    </NEXT_NODE>
  </NEXT_NODE>
</NODE_T>

但是我不相信这样的类型可以被声明为列数据类型并因此将它们直接保存在关系表中(尽管诸如在 anydata 内部或转换为 xml 之类的间接方法会起作用)。

另外我还没有真正在实际场景中使用过这个,我不知道是否有递归限制或者这通常有多健壮。

【讨论】:

    【解决方案2】:

    没有这样的选择,

    但是根据关于 Nested Object Types 的 Oracle 文档,您应该使用 Collection 来保存相同的类型(不使用递归)

    集合类型是用于建模多值属性的对象数据类型。嵌套表是集合类型

    例如:

    describe dm_nested_categoricals
    DM_NESTED_CATEGORICALS TABLE OF SYS.DM_NESTED_CATEGORICAL
    

    【讨论】:

    • 这是一个对象类型嵌套表的示例,但这与递归定义的对象类型不同。我不相信您可以在 Oracle 数据库对象类型中做到这一点。
    【解决方案3】:

    可以定义递归(嵌套)类

    是的,可以这样做,但只能达到inheritance。创建对象时,您必须确保它不是Final。请看下面的演示:

    --Created an Object which is not `Final`
        CREATE OR REPLACE TYPE prnt_obj AS OBJECT (
            id     NUMBER,
            name   VARCHAR2(10)
        )
        NOT INSTANTIABLE NOT FINAL; --<-- This make sure that the object can be nested.
        /
        --Created a type where the above table columns can be nested.
        CREATE OR REPLACE  TYPE chld_obj UNDER prnt_obj (
            chld_id     NUMBER,
            chld_name   VARCHAR2(10)
        );
        /
        --Created a table of Object.
        CREATE TABLE TAB of chld_obj;
        /
        --Inserted record to the table
        INSERT INTO tab VALUES (
            1,
            'XXX',
            2,
            'YYY'
        );
        --selected records
        SELECT * FROM tab;
        /
    

    【讨论】:

      猜你喜欢
      • 2010-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 2020-04-21
      相关资源
      最近更新 更多