Oracle OR - 如何保证嵌套的 table 具有对超类型的所有子类型的引用
Oracle OR - how to guarantee that a nested table has references to all the subtypes of a supertype
我正在设计对象关系模型数据库。我有一个名为 "topico_t" 的超类型和该超类型的 4 个子类型,分别名为 "anotacao_t"、"tarefa_t"、"memo_t" 和 "contacto_t"。请在此处查看 DDL 片段:
CREATE OR REPLACE TYPE categoria_t AS OBJECT(
nome VARCHAR2(25),
pai REF categoria_t
);
CREATE OR REPLACE TYPE categoria_tab_t AS TABLE OF REF categoria_t;
CREATE OR REPLACE TYPE topico_t AS OBJECT(
titulo VARCHAR2(100),
ultimaAlteracao DATE,
categorias categoria_tab_t
--referencias topico_tab_t
) NOT FINAL;
CREATE OR REPLACE TYPE topico_tab_t AS TABLE OF REF topico_t;
ALTER TYPE topico_t ADD ATTRIBUTE referencias topico_tab_t CASCADE;
CREATE OR REPLACE TYPE periodo_t AS OBJECT(
inicio DATE,
fim DATE
);
CREATE OR REPLACE TYPE repeticao_t AS OBJECT(
frequencia VARCHAR2(10),
duracao periodo_t
);
CREATE OR REPLACE TYPE anotacao_t UNDER topico_t(
periodo periodo_t,
repeticao repeticao_t
);
CREATE OR REPLACE TYPE telefone_t AS OBJECT(
numero VARCHAR2(25)
);
CREATE OR REPLACE TYPE telefone_tab_t AS TABLE OF telefone_t;
CREATE OR REPLACE TYPE morada_t AS OBJECT(
rua VARCHAR2(100),
localidade VARCHAR2(50),
codigoPostal VARCHAR2(10)
);
CREATE OR REPLACE TYPE morada_tab_t AS TABLE OF morada_t;
CREATE OR REPLACE TYPE contacto_t UNDER topico_t(
telefones telefone_tab_t,
moradas morada_tab_t,
email VARCHAR2(100),
url VARCHAR2(150)
);
CREATE OR REPLACE TYPE tarefa_t UNDER topico_t(
dataFim DATE,
completo NUMBER(1,0),
conteudo VARCHAR2(255)
);
CREATE OR REPLACE TYPE memo_t UNDER topico_t(
conteudo VARCHAR2(255)
);
CREATE TABLE categorias OF categoria_t;
CREATE TABLE topicos OF topico_t
NESTED TABLE categorias STORE AS categorias_nested
NESTED TABLE referencias STORE AS referencias_nested;
所以,然后我 填充 这个 table "topicos" 用这个:
INSERT INTO topicos VALUES (tarefa_t(
'Dissertacao',
TO_DATE('2018/02/13', 'YYYY/MM/DD'),
categoria_tab_t((select ref(c) from categorias c where nome='FEUP')),
topico_tab_t((select ref(t) from topicos t where titulo='Diogo Pereira'), -- which is an object of the subtype "contacto_t"
(select ref(t) from topicos t where titulo='Comecar a dissertacao'), -- which is an object of the subtype "memo_t"
(select ref(t) from topicos t where titulo='Apresentar Dissertacao'), -- which is an object of the subtype "tarefa_t"
(select ref(t) from topicos t where titulo='Reuniao com Orientador da Dissertacao')), -- which is an object of the subtype "anotacao_t"
TO_DATE('2018/08/13', 'YYYY/MM/DD'),
0,
'Dissertacao all over again'));
所以,我必须构建一个查询,甚至是一个 PL/SQL 块,return 将 table "topicos" 的所有行都包含在内,在嵌套的 table "referencias" 中,上面提到的这 4 个子类型中的每一个都有一个实例对象。理想情况下,此查询将 return 我那一行(在上面 INSERT 中提到)。
最诚挚的问候,祝您劳动节愉快! ;)
您的 DDL 代码有误。您正在创建一个基本类型 topico_t
,然后是该类型下的一些子类型,但您只创建了一个 table 基本类型对象。这样做的问题是您期望 table 包含任何子类型的对象,但由于所谓的 object slicing 而不是这种情况。您创建的 table 只有与您为基本类型定义的字段相对应的列。
因此,您需要为最终实例化的所有子类型创建 table。您应该只为基类型创建一个 table 如果实例化该类型是有意义的,也就是说,如果不属于任何子类型的基类型的对象可能存在。
完成此操作后,您尝试编写的查询应使用函数 TREAT。请注意,根据 documentation,此函数 returns NULL
当表达式不是您要转换为的类型时,因此您需要编写的查询应为当从嵌套的 table 中选择并尝试转换为您创建的每个子类型时,测试是否至少有一行具有非空结果字段很简单。查看文档中的示例以了解如何使用此功能。
我正在设计对象关系模型数据库。我有一个名为 "topico_t" 的超类型和该超类型的 4 个子类型,分别名为 "anotacao_t"、"tarefa_t"、"memo_t" 和 "contacto_t"。请在此处查看 DDL 片段:
CREATE OR REPLACE TYPE categoria_t AS OBJECT(
nome VARCHAR2(25),
pai REF categoria_t
);
CREATE OR REPLACE TYPE categoria_tab_t AS TABLE OF REF categoria_t;
CREATE OR REPLACE TYPE topico_t AS OBJECT(
titulo VARCHAR2(100),
ultimaAlteracao DATE,
categorias categoria_tab_t
--referencias topico_tab_t
) NOT FINAL;
CREATE OR REPLACE TYPE topico_tab_t AS TABLE OF REF topico_t;
ALTER TYPE topico_t ADD ATTRIBUTE referencias topico_tab_t CASCADE;
CREATE OR REPLACE TYPE periodo_t AS OBJECT(
inicio DATE,
fim DATE
);
CREATE OR REPLACE TYPE repeticao_t AS OBJECT(
frequencia VARCHAR2(10),
duracao periodo_t
);
CREATE OR REPLACE TYPE anotacao_t UNDER topico_t(
periodo periodo_t,
repeticao repeticao_t
);
CREATE OR REPLACE TYPE telefone_t AS OBJECT(
numero VARCHAR2(25)
);
CREATE OR REPLACE TYPE telefone_tab_t AS TABLE OF telefone_t;
CREATE OR REPLACE TYPE morada_t AS OBJECT(
rua VARCHAR2(100),
localidade VARCHAR2(50),
codigoPostal VARCHAR2(10)
);
CREATE OR REPLACE TYPE morada_tab_t AS TABLE OF morada_t;
CREATE OR REPLACE TYPE contacto_t UNDER topico_t(
telefones telefone_tab_t,
moradas morada_tab_t,
email VARCHAR2(100),
url VARCHAR2(150)
);
CREATE OR REPLACE TYPE tarefa_t UNDER topico_t(
dataFim DATE,
completo NUMBER(1,0),
conteudo VARCHAR2(255)
);
CREATE OR REPLACE TYPE memo_t UNDER topico_t(
conteudo VARCHAR2(255)
);
CREATE TABLE categorias OF categoria_t;
CREATE TABLE topicos OF topico_t
NESTED TABLE categorias STORE AS categorias_nested
NESTED TABLE referencias STORE AS referencias_nested;
所以,然后我 填充 这个 table "topicos" 用这个:
INSERT INTO topicos VALUES (tarefa_t(
'Dissertacao',
TO_DATE('2018/02/13', 'YYYY/MM/DD'),
categoria_tab_t((select ref(c) from categorias c where nome='FEUP')),
topico_tab_t((select ref(t) from topicos t where titulo='Diogo Pereira'), -- which is an object of the subtype "contacto_t"
(select ref(t) from topicos t where titulo='Comecar a dissertacao'), -- which is an object of the subtype "memo_t"
(select ref(t) from topicos t where titulo='Apresentar Dissertacao'), -- which is an object of the subtype "tarefa_t"
(select ref(t) from topicos t where titulo='Reuniao com Orientador da Dissertacao')), -- which is an object of the subtype "anotacao_t"
TO_DATE('2018/08/13', 'YYYY/MM/DD'),
0,
'Dissertacao all over again'));
所以,我必须构建一个查询,甚至是一个 PL/SQL 块,return 将 table "topicos" 的所有行都包含在内,在嵌套的 table "referencias" 中,上面提到的这 4 个子类型中的每一个都有一个实例对象。理想情况下,此查询将 return 我那一行(在上面 INSERT 中提到)。
最诚挚的问候,祝您劳动节愉快! ;)
您的 DDL 代码有误。您正在创建一个基本类型 topico_t
,然后是该类型下的一些子类型,但您只创建了一个 table 基本类型对象。这样做的问题是您期望 table 包含任何子类型的对象,但由于所谓的 object slicing 而不是这种情况。您创建的 table 只有与您为基本类型定义的字段相对应的列。
因此,您需要为最终实例化的所有子类型创建 table。您应该只为基类型创建一个 table 如果实例化该类型是有意义的,也就是说,如果不属于任何子类型的基类型的对象可能存在。
完成此操作后,您尝试编写的查询应使用函数 TREAT。请注意,根据 documentation,此函数 returns NULL
当表达式不是您要转换为的类型时,因此您需要编写的查询应为当从嵌套的 table 中选择并尝试转换为您创建的每个子类型时,测试是否至少有一行具有非空结果字段很简单。查看文档中的示例以了解如何使用此功能。