Oracle Object包含相同对象的列表

时间:2016-08-19 13:52:58

标签: oracle plsql

我目前正在努力解决PL / SQL问题,而且还没有找到明确的答案。问题是,我有一个T类型的对象,它可以包含相同类型T的对象列表。

假设我有一个TPerson类型。 TPerson由名称和子项列表定义。所以我有一个祖父,他的两个儿子,第一个有两个女儿。

在PL / SQL中,经过一些研究,我做到了这一点:

CREATE OR REPLACE TYPE TPerson IS OBJECT 
    (
     Name             VARCHAR2(30),
     Children         REF TPersonList,
     constructor function TPerson(name VARCHAR2) return self as result
    );

CREATE OR REPLACE TYPE body TPerson as
   constructor function TPerson(aname VARCHAR2) return self as result is
       begin
           Name       := aname;
           Children   := TPersonList();
           return;
       end;
   end;

CREATE OR REPLACE TYPE TPersonList IS TABLE OF REF TPerson';

一切都没有异常。但是TPerson类型编译不正确,我有这个编译错误:

pls-00532 target of ref must be a complete or incomplete object type

这是我第一次使用这个REF的东西。我甚至不确定我是否正确使用它。在我看来,这不是一个非常好的方式('儿童'的事情),但我没有选择。因此,如果有人能够向我解释实现这一目标的正确方法,那将对我有很大的帮助......

1 个答案:

答案 0 :(得分:0)

我不确定某个对象类型是否可以拥有一个类型相同的集合成员,而该集合必须能够在集合之前的对象类型和对象类型之前定义集合。要打破循环依赖,需要以下列方式引入一个间接级别(警告未经测试的伪代码如下):

-- supertype
create type object_t is object;
create type object_list_t is table of ref object_t;

-- subtype
create type person_t under object_t (
 name varchar2(20)
,children object_list_t
);

然后在person_t的实现中,使用treat从超类型缩小到子类型。

另一个想法是在特定关系表中建立对象的关系。请参阅下面的示例。

首先创建一个简单的人类型:

create type person_t is object (
 name varchar2(20)
);
/
show errors

create table persons of person_t;

insert into persons values(person_t('Grandfather'));
insert into persons values(person_t('Father'));
insert into persons values(person_t('Mother'));
insert into persons values(person_t('Son 1'));
insert into persons values(person_t('Daughter 1'));
insert into persons values(person_t('Son 2'));

其次为父子关系创建一个表:

create table x (
 parent ref person_t
,child ref person_t
);

-- build a family tree
insert into x values(
 (select ref(p) from persons p where name = 'Grandfather')
,(select ref(p) from persons p where name = 'Father')
);

insert into x values(
 (select ref(p) from persons p where name = 'Father')
,(select ref(p) from persons p where name = 'Son 1')
);

insert into x values(
 (select ref(p) from persons p where name = 'Father')
,(select ref(p) from persons p where name = 'Son 2')
);

insert into x values(
 (select ref(p) from persons p where name = 'Father')
,(select ref(p) from persons p where name = 'Daughter 1')
);

insert into x values(
 (select ref(p) from persons p where name = 'Mother')
,(select ref(p) from persons p where name = 'Son 1')
);

insert into x values(
 (select ref(p) from persons p where name = 'Mother')
,(select ref(p) from persons p where name = 'Son 2')
);

insert into x values(
 (select ref(p) from persons p where name = 'Mother')
,(select ref(p) from persons p where name = 'Daughter 1')
);

现在,您可以使用旧的SQL遍历族树。

column parent format a30
column child format a30

select deref(child) as child from x where deref(parent).name = 'Father';

CHILD(NAME)
------------------------------
PERSON_T('Son 1')
PERSON_T('Son 2')
PERSON_T('Daughter 1')

select deref(parent) as parent, deref(child) as child
from x
start with deref(parent).name = 'Grandfather'
connect by prior child = parent
;

PARENT(NAME)                   CHILD(NAME)
------------------------------ ------------------------------
PERSON_T('Grandfather')        PERSON_T('Father')
PERSON_T('Father')             PERSON_T('Son 1')
PERSON_T('Father')             PERSON_T('Son 2')
PERSON_T('Father')             PERSON_T('Daughter 1')

ref中解释了derefSQL>@/path/to/my/query/myQueries.sql SQL>/ 函数。如果您正在使用Oracle对象类型,那么这是您应该熟悉的文档。