我目前正在努力解决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的东西。我甚至不确定我是否正确使用它。在我看来,这不是一个非常好的方式('儿童'的事情),但我没有选择。因此,如果有人能够向我解释实现这一目标的正确方法,那将对我有很大的帮助......
答案 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
中解释了deref
和SQL>@/path/to/my/query/myQueries.sql
SQL>/
函数。如果您正在使用Oracle对象类型,那么这是您应该熟悉的文档。