【问题标题】:Oracle OR - how to guarantee that a nested table has references to all the subtypes of a supertypeOracle OR - 如何保证嵌套表具有对超类型的所有子类型的引用
【发布时间】:2017-05-01 15:45:37
【问题描述】:

我正在设计一个对象关系模型数据库。我有一个名为“topico_t”的超类型和这个超类型的 4 个子类型,名为“anotacao_t”、“tarefa_t”、“memo_t”和“contacto_t”。在这里查看DDL sn-p

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;

所以,然后我填充这个表“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 块,它返回表“topicos”的所有行,其中至少包含嵌套表“referencias”中的每个实例对象上面提到的4个亚型。理想情况下,此查询将返回该行(在上面 INSERT 中提到)。

最好的问候,并希望你有一个美好的劳动节! ;)

【问题讨论】:

    标签: sql oracle object-relational-model


    【解决方案1】:

    您的 DDL 代码有误。您正在创建一个基本类型 topico_t,然后是该类型下的一些子类型,但您只创建了一个基本类型对象表。这样做的问题是您希望该表包含任何子类型的对象,但由于所谓的object slicing,情况并非如此。您创建的表只有与您为基本类型定义的字段相对应的列。

    因此,您需要为最终将实例化的所有子类型创建表。只有在对基类型进行实例化有意义的情况下,才应该为基类型创建表,也就是说,如果不属于任何子类型的基类型的对象可能存在。

    完成此操作后,您尝试编写的查询应使用函数 TREAT。请注意,根据documentation,当表达式不是您要转换为的类型时,此函数返回NULL,因此您需要编写的查询应该像测试至少有从嵌套表中选择并尝试转换为您创建的每个子类型时,一行具有非空结果字段。查看文档中的示例以了解如何使用此功能。

    【讨论】:

      猜你喜欢
      • 2022-08-09
      • 2016-03-26
      • 1970-01-01
      • 1970-01-01
      • 2020-03-23
      • 1970-01-01
      • 1970-01-01
      • 2012-03-16
      • 2018-06-16
      相关资源
      最近更新 更多