banco de dados 2
DESCRIPTION
SGDBOR Oracle 11gTRANSCRIPT
Capítulo 4: BDOR – SGBD Oracle 11g 2
SGBDOR Oracle 11g
O SGBDOR ORACLE 11g oferece diferentes tipos de objetos:
Tipos de Objetos (TADs)
Nested Tables (Tabelas Aninhadas)
Varying Arrays (Varrays)
Large Objects (LOBs)
References (REF)
Object View (Visão de Objetos)
No entanto, há algumas diferenças com o padrão SQL:1999...
Capítulo 4: BDOR – SGBD Oracle 11g 3
SGBDOR Oracle 11g
Conceitos Básicos
Tipo de Objeto
Método
Evolução de Tipo (ALTER TYPE)
Herança de Tipo
Tabela de Objeto
Objeto de Linha e Objeto de Coluna
Referência de Objeto
Coleção de Objetos
Capítulo 4: BDOR – SGBD Oracle 11g 4
Exemplo - UMLE
squem
a C
once
itual
Capítulo 4: BDOR – SGBD Oracle 11g 5
Esquema Relacional
Projeto BD Relacional
Capítulo 4: BDOR – SGBD Oracle 11g 6
Esquema
Objeto-
Relacional
Capítulo 4: BDOR – SGBD Oracle 11g 7
Definindo os Tipos
2
1
3
4
5
6
7
*
* Endereço de entrega não é necessariamente o endereço do cliente
Capítulo 4: BDOR – SGBD Oracle 11g 8
Tipos de Objetos (Object Types)
Tipo de objeto é um tipo abstrato de dados (TAD), ou seja, um Structured Type em SQL:1999
TAD é um tipo de dado definido pelo usuárioque encapsula propriedades (atributos) e comportamento (métodos)
Corresponde ao “molde” de um objeto
Não aloca espaço de armazenamento
Não pode armazenar dados
Por default, são definidos como FINAL
(herança)
Capítulo 4: BDOR – SGBD Oracle 11g 9
Um Tipo de Objeto é um esquema de objeto com 3 componentes: Nome obrigatório
Atributos obrigatório
Métodos facultativo (já vem com construtor)
Um Tipo de Objeto pode ser usado para: Definir o domínio de campos (“column object”) de
tabelas normais (relacionais)
Definir o tipo dos atributos de TADs (“embedded object”)
Criar uma tabela de objetos (“object table”)
Criar uma variável a partir de um tipo de dados
Tipos de Objetos (Object Types)
Capítulo 4: BDOR – SGBD Oracle 11g 10
Tipos de Objetos (Object Types)
Um tipo de objeto em Oracle possui a seguinte
estrutura:
Capítulo 4: BDOR – SGBD Oracle 11g 11
Tipos de Objetos (Object Types)
Exemplo de especificação da interface pública
de um objeto
Sintaxe resumida:
CREATE [OR REPLACE] TYPE nome_tipo AS
OBJECT (
[lista de atributos]
[lista de métodos]
) [ FINAL | NOT FINAL ];
Capítulo 4: BDOR – SGBD Oracle 11g 12
Tipos de Objetos (Object Types)
Pode ser usado da mesma forma que é usado um tipo primitivo
-- Para definir o tipo de de dados uma coluna de uma tabela relacional
CREATE TABLE tb_contatos (
contato tp_pessoa,
dt_contato DATE );
CREATE TABLE tb_domicilio (
local tp_ponto,
endereco VARCHAR2 (80) );
-- Para definir o tipo de dados de um atributo de um TADCREATE TYPE tp_contatos AS OBJECT (
contato tp_ pessoa,
dt_contato DATE );
CREATE TYPE tp_domicilio AS OBJECT (
local tp_ponto,
endereco VARCHAR2 (80) );
Tipos de Objetos (Object Types)
-- Como um tipo de dados de uma variável
DECLARE
v_pessoa tp_pessoa;
BEGIN
SELECT contato
INTO v_pessoa
FROM tb_contatos
WHERE rownum <= 1;
DBMS_OUTPUT.PUT_LINE(v_pessoa.nome);
END;
Capítulo 4: BDOR – SGBD Oracle 11g 13
Recuperando o tipo de uma Object
Table
SELECT table_type
FROM user_object_tables
WHERE table_name = 'ENTREGA_TAB' ;
Capítulo 4: BDOR – SGBD Oracle 11g 14
Capítulo 4: BDOR – SGBD Oracle 11g 15
CREATE TYPE ENDERECO_TYP AS OBJECT
(rua VARCHAR2(50),
cidade VARCHAR2(25),
estado CHAR(2),
cep NUMBER);
CREATE TABLE PESSOAS
(nome VARCHAR2(25),
endereço ENDERECO_TYP);
ENDEREÇO_TYP é usado para
definir o tipo (domínio) da coluna
Endereço da tabela PESSOAS
Tipos de Objetos
Capítulo 4: BDOR – SGBD Oracle 11g 16
Não é possível ocorrer uma inserção de dados em
PESSOA_TYP, porque um tipo de objeto apenas descreve
dados, mas não os armazena
CREATE TYPE ENDERECO_TYP AS OBJECT
(rua VARCHAR2(50),
cidade VARCHAR2(25),
estado CHAR(2),
cep NUMBER);
CREATE TYPE PESSOA_TYP AS OBJECT
(nome VARCHAR2(25),
endereco ENDERECO_TYP);
ENDEREÇO_TYP é usado
para definir o tipo do
atributo Endereco do tipo
PESSOA_TYP
Tipos de Objetos
Capítulo 4: BDOR – SGBD Oracle 11g 17
Para armazenar dados é necessário a criação de uma tabela a partir
de um tipo de objeto.
CREATE TYPE pessoa_ty AS OBJECT
(Nome VARCHAR2(25),
CPF NUMBER,
Endereco ENDERECO_TY);
CREATE TABLE pessoas OF pessoa_ty
(CPF primary key);
CREATE TABLE pessoas2 OF pessoa_ty;
As tabelas de objetos PESSOAS e PESSOAS2 irão armazenar dados
com a estrutura do tipo PESSOA_TY
Tipos de Objetos
Capítulo 4: BDOR – SGBD Oracle 11g 18
Exemplo com Métodos
CREATE TYPE person_typ AS OBJECT (
idno NUMBER,
first_name VARCHAR2(20),
last_name VARCHAR2(25),
email VARCHAR2(25),
phone VARCHAR2(20),
MAP MEMBER FUNCTION get_idno RETURN NUMBER,
MEMBER PROCEDURE display_details (SELF IN OUT
person_typ));
Atenção: (SELF IN OUT person_type ) é opcional!
Capítulo 4: BDOR – SGBD Oracle 11g 19
Exemplo (cont.)
CREATE TYPE BODY person_typ AS
MAP MEMBER FUNCTION get_idno RETURN NUMBER IS
BEGIN -- método usado para comparação de objetos
RETURN idno;
END;
MEMBER PROCEDURE display_details (SELF IN OUT person_typ) IS
BEGIN
-- use the PUT_LINE procedure of the DBMS_OUTPUT package to display details
DBMS_OUTPUT.PUT_LINE(TO_CHAR(idno) || ' ' || first_name || ' ' || last_name);
DBMS_OUTPUT.PUT_LINE(email || ' ' || phone);
END;
END;
Capítulo 4: BDOR – SGBD Oracle 11g 20
Exemplo (cont.)
CREATE TABLE person_tab OF person_typ;
INSERT INTO person_tab VALUES (person_typ(1,‟JOSE‟,‟SILVA‟,‟[email protected]‟,‟88737390‟));
SELECT p.display_details()
FROM person_tab p;
ERRO na linha 1:
ORA-06553: PLS-222: nπo existe nenhuma funτπo com o nome 'DISPLAY_DETAILS'
nesta abrangΩncia
DISPLAY_DETAILS está implementado como uma procedure e deveria estar implementado como uma função
Capítulo 4: BDOR – SGBD Oracle 11g 21
Exemplo (cont.)
DECLARE
v_person person_typ;
BEGIN
SELECT VALUE(p)
INTO v_person
FROM person_tab p
WHERE p.idno = 1;
v_person.display_details();
END;
/
Capítulo 4: BDOR – SGBD Oracle 11g 22
Inserindo Dados
Exemplo
CREATE TABLE contacts (
contact person_typ,
contact_date DATE );
INSERT INTO contacts VALUES (
person_typ (65, 'Verna', 'Mills', '[email protected]',
'1-800-555-4412'), '24-JUN-2003');
construtor
Capítulo 4: BDOR – SGBD Oracle 11g 23
Inserindo com NULL
INSERT INTO contacts VALUES (person_typ
(NULL, NULL, NULL,NULL,NULL), '24 Jun 2003' );
INSERT INTO contacts VALUES (NULL, '25 Jun
2003' );
1
2
Capítulo 4: BDOR – SGBD Oracle 11g 24
Inserindo com NULL
Em ambos os casos, o SGBD Oracle aloca espaço em CONTACTS para uma nova linha e atualiza a coluna CONTACT_DATE de acordo com o valor fornecido Caso 1: SGBD Oracle aloca espaço para um objeto
na coluna CONTACT e atualiza cada atributo para NULL ((null, null, null, null, null),‟08-JAN-2009‟)
Caso 2: SGBD Oracle atualiza o campo CONTACT para NULL e não aloca espaço para um objeto na coluna CONTACT (null,‟08-JAN-2009‟)
Capítulo 4: BDOR – SGBD Oracle 11g 25
Restrições de Integridade (Constraints)
São definidas na tabela normal ou de objetos
CREATE TABLE department_mgrs (
dept_no NUMBER CONSTRAINT dept_no_pk PRIMARY KEY,
dept_name CHAR(20),
dept_mgr person_typ,
dept_loc location_typ,
CONSTRAINT dept_loc_cons1
UNIQUE (dept_loc.building_no, dept_loc.city),
CONSTRAINT dept_loc_cons2 CHECK (dept_loc.city IN („NY‟,‟CHI‟)));
INSERT INTO department_mgrs VALUES
(101, 'Physical Sciences',
person_typ(65,'Vrinda Mills', '1-800-555-4412'),
location_typ(300, 'Palo Alto'));
nome da constraint dado pelo usuário
construtores
Capítulo 4: BDOR – SGBD Oracle 11g 26
Trigger em Objetos Tipados
CREATE TABLE movement (
idno NUMBER,
old_office location_typ,
new_office location_typ);
CREATE TRIGGER my_trigger
BEFORE UPDATE OF office_loc ON office_tab
FOR EACH ROW
WHEN (new.office_loc.city = 'Redwood Shores')
BEGIN
IF :new.office_loc.building_no = 600 THEN
INSERT INTO movement (idno, old_office, new_office)
VALUES (:old.occupant.idno, :old.office_loc, :new.office_loc);
END IF;
END;
coluna tabela
CREATE TABLE office_tab (
office_loc location_typ,
occupant occupant_typ);
CREATE TYPE location_typ AS OBJECT(
city VARCHAR2(30),
building_no NUMBER);
CREATE TYPE occupant_typ AS OBJECT(
idno NUMBER);
Capítulo 4: BDOR – SGBD Oracle 11g 27
Métodos
São funções ou procedimentos declarados na definição de um tipo de objeto
Exigem o uso de parênteses (mesmo sem parâmetros)
O uso de () é para diferenciar o método de um procedimento ou função comum
Podem ser: MEMBER ou STATIC
MAP ou ORDER (para ordenação)
Construtor
Por default, os métodos são definidos como NOT
FINAL (permite que sejam sobrescritos)
Capítulo 4: BDOR – SGBD Oracle 11g 28
Métodos
Um Object Type...
sempre possui um método construtor
pode possuir zero ou mais métodos membro/static
pode possuir zero ou um método map ou um método
order, porém não os dois
Exemplo de chamada de método sem
parâmetros
SELECT c.contact.get_idno() AS idno
FROM contacts c;
Capítulo 4: BDOR – SGBD Oracle 11g 29
Métodos
MEMBER
São os métodos mais comuns
Implementam as operações das instâncias do tipo
São chamados através da qualificação de objeto
objeto.método()
SELF não precisa ser declarado, mas, se for, deverá
ser sempre o primeiro parâmetro
Capítulo 4: BDOR – SGBD Oracle 11g 30
Exemplo: Member MethodCREATE TYPE solid_typ AS OBJECT (
len INTEGER,
wth INTEGER,
hgt INTEGER,
MEMBER FUNCTION volume RETURN INTEGER,
MEMBER FUNCTION surface RETURN INTEGER,
MEMBER PROCEDURE display (SELF IN OUT solid_typ));
CREATE TYPE BODY solid_typ AS
MEMBER FUNCTION volume RETURN INTEGER IS
BEGIN
RETURN len * wth * hgt;
-- RETURN SELF.len * SELF.wth * SELF.hgt; -- equivalent to previous line
END;
MEMBER FUNCTION surface RETURN INTEGER IS
BEGIN -- not necessary to include SELF prefix in following line
RETURN 2 * (len * wth + len * hgt + wth * hgt);
END;
MEMBER PROCEDURE display (SELF IN OUT solid_typ) IS
BEGIN
DBMS_OUTPUT.PUT_LINE('Length: ' || len || ' - ' || 'Width: ' || wth || ' - ' || 'Height: ' || hgt);
DBMS_OUTPUT.PUT_LINE('Volume: ' || volume || ' - ' || 'Surface area: ' || surface);
END;
END;
Capítulo 4: BDOR – SGBD Oracle 11g 31
Exemplo: Member MethodCREATE TABLE solid_tab OF solid_typ;
INSERT INTO solid_tab VALUES (solid_typ(2,2,2));
SELECT s.volume() AS volume, s.surface() AS superficie
FROM solid_tab s;
SET SERVEROUTPUT ON
DECLARE
obj solid_typ;
BEGIN
SELECT VALUE(o)
INTO obj
FROM solid_tab o;
solid_typ.display(obj);
END;
/
Capítulo 4: BDOR – SGBD Oracle 11g 32
Métodos
Construtor Criado implicitamente ao criar um tipo de objeto
Nome é exatamente igual ao nome do tipo
Pode haver mais de um construtor (overloadable)
Exemplo
INSERT INTO tb_contatos VALUES (
Person_typ (65, 'Pedro', 'Medeiros', '[email protected]', '83-3337-3333'), SYSDATE);
Capítulo 4: BDOR – SGBD Oracle 11g 33
Exemplo: Método Construtor
(Sobrecarga)
CREATE TYPE t_person2 AS OBJECT (
id INTEGER,
first_name VARCHAR2(10),
last_name VARCHAR2(10),
dob DATE,
phone VARCHAR2(12),
CONSTRUCTOR FUNCTION t_person2 (p_id INTEGER, p_first_name VARCHAR2, p_last_name VARCHAR2) RETURN SELF AS RESULT);
Exemplo: Método Construtor
(Sobrecarga)
CREATE TYPE BODY t_person2 AS
CONSTRUCTOR FUNCTION t_person2(
p_id INTEGER,
p_first_name VARCHAR2,
p_last_name VARCHAR2
) RETURN SELF AS RESULT IS
BEGIN
SELF.id := p_id;
SELF.first_name := p_first_name;
SELF.last_name := p_last_name;
SELF.dob := SYSDATE;
SELF.phone := '555-1212';
RETURN;
END;
CREATE TABLE object_customers2 OF t_person2;
INSERT INTO object_customers2 VALUES (
t_person2(1,'Jeff', 'Jones'));
Capítulo 4: BDOR – SGBD Oracle 11g 34
Capítulo 4: BDOR – SGBD Oracle 11g 35
Static Method
Usados para operações que são globais ao tipo
e não precisam se reportar a uma instância
particular
Não possui parâmetro SELF
São chamados nos tipos de dados, não em uma
instância particular
Chamado da seguinte forma:
type_name.method()
Capítulo 4: BDOR – SGBD Oracle 11g 36
CREATE OR REPLACE TYPE alunosbd2_typ AS OBJECT(
matricula NUMBER,
nome VARCHAR2(20),
semestre NUMBER,
ano NUMBER,
STATIC PROCEDURE atualiza (p_semestre NUMBER));
CREATE TABLE alunosbd2_tab OF alunosbd2_typ;
INSERT INTO alunosbd2_tab VALUES (1,'JOSE',20101,null);
INSERT INTO alunosbd2_tab VALUES (2,'MARIA',20111,null);
INSERT INTO alunosbd2_tab VALUES (3,'PEDRO',20111,null);
Exemplo 01: Static Method
Capítulo 4: BDOR – SGBD Oracle 11g 37
CREATE OR REPLACE TYPE BODY alunosbd2_typ AS
STATIC PROCEDURE atualiza (p_semestre NUMBER) IS
BEGIN
UPDATE alunosbd2_tab
SET ano = TO_NUMBER(SUBSTR(TO_CHAR(semestre),1,4))
WHERE semestre = p_semestre;
END;
END;
BEGIN
alunosbd2_typ.atualiza(20111);
END;
SELECT a.* FROM alunosbd2_tab a;
Exemplo 01: Static Method
Capítulo 4: BDOR – SGBD Oracle 11g 38
Exemplo 02: Static MethodCREATE TYPE atype AS OBJECT(
a1 NUMBER,
STATIC PROCEDURE newa (p1 NUMBER, tabname VARCHAR2, schname VARCHAR2));
CREATE TYPE BODY atype AS
STATIC PROCEDURE newa (p1 NUMBER, tabname VARCHAR2, schname VARCHAR2) IS
sqlstmt VARCHAR2(100);
BEGIN
sqlstmt := 'INSERT INTO ' || schname || '. ' || tabname || ' VALUES (atype(:1))';
EXECUTE IMMEDIATE sqlstmt USING p1;
END;
END;
CREATE TABLE atab OF atype;
BEGIN
atype.newa(1000, 'atab', 'HR');
END;
construtor
valor, tabela e esquema (usuário do BD)
Capítulo 4: BDOR – SGBD Oracle 11g 39
Métodos para Comparação de Objetos
Motivação
DROP TABLE emp_table;
DROP TYPE emp_type;
CREATE OR REPLACE TYPE end_type AS
OBJECT (
rua VARCHAR2(30),
bairro VARCHAR2(30));
Capítulo 4: BDOR – SGBD Oracle 11g 40
Métodos para Comparação de Objetos
CREATE OR REPLACE TYPE emp_type AS OBJECT (
nome VARCHAR2(30),
endr end_type);
CREATE TABLE emp_table OF emp_type;
INSERT INTO emp_table VALUES
(emp_type('JOSE',end_type('RUA DO
SOL','CATOLE')));
INSERT INTO emp_table VALUES
('MARIA',end_type('RUA DA LUA','CATOLE'));
Capítulo 4: BDOR – SGBD Oracle 11g 41
Métodos para Comparação de Objetos
SELECT m.nome
FROM emp_table m
ORDER BY m.endr;
order by m.endr
*
ERRO na linha 3:
ORA-22950: não pode ORDER objetos sem o
método MAP ou ORDER
Capítulo 4: BDOR – SGBD Oracle 11g 42
Métodos para Comparação de Objetos
MAP ou ORDER São “funções” opcionais e servem para comparar
objetos
São mutuamente exclusivas!
MAP Implementa o MAP do SQL:1999, retornando um valor de tipo
built-in
Não exige parâmetro de entrada
MAP compara vários objetos (ex.: ORDER BY)
ORDER Implementa o RELATIVE WITH do SQL:1999, retornando
negativo, zero ou positivo
Exige como parâmetro um objeto do mesmo tipo
Compara o objeto corrente (SELF) com o objeto do parâmetro
Capítulo 4: BDOR – SGBD Oracle 11g 43
Métodos para Comparação de ObjetosExemplo de MAP
CREATE TYPE rectangle_typ AS OBJECT (
len NUMBER,
wid NUMBER,
MAP MEMBER FUNCTION area RETURN NUMBER);
CREATE TYPE BODY rectangle_typ AS
MAP MEMBER FUNCTION area RETURN NUMBER IS
BEGIN
RETURN len * wid;
END;
END;
Capítulo 4: BDOR – SGBD Oracle 11g 44
Métodos para Comparação de ObjetosExemplo de MAP
create table figura (
codigo NUMBER,
dimensao rectangle_typ);
insert into figura values (10,rectangle_typ(2,2));
insert into figura values (11,rectangle_typ(3,3));
SELECT codigo
FROM figura
ORDER BY dimensao DESC;
Capítulo 4: BDOR – SGBD Oracle 11g 45
Métodos para Comparação de Objetos
Outro Exemplo de MAP
CREATE OR REPLACE TYPE end_type AS OBJECT (
rua VARCHAR2(30),
bairro VARCHAR2(30),
MAP MEMBER FUNCTION compare RETURN VARCHAR2);
Ou... ALTER TYPE end_type ADD MAP MEMBER FUNCTION compare RETURN VARCHAR2 CASCADE;
CREATE OR REPLACE TYPE BODY end_type AS
MAP MEMBER FUNCTION compare RETURN VARCHAR2 IS
BEGIN
RETURN rua;
END;
END;
Capítulo 4: BDOR – SGBD Oracle 11g 46
Métodos para Comparação de Objetos
CREATE TABLE emp_table
(nome VARCHAR2(400),
endr end_type);
SELECT m.nome
FROM emp_table m
ORDER BY m.endr;
NOME
-----------------------------
MARIA
JOSE
-- Rua da Lua
-- Rua do Sol
Ou...
SELECT m.nome
FROM emp_table m
ORDER BY m.endr.rua;
Não precisaria de MAP!
Capítulo 4: BDOR – SGBD Oracle 11g 47
Métodos para Comparação de ObjetosExemplo de ORDER
CREATE TYPE location_typ AS OBJECT (
building_no NUMBER,
city VARCHAR2(40),
ORDER MEMBER FUNCTION match (l location_typ) RETURN INTEGER );
CREATE TYPE BODY location_typ AS
ORDER MEMBER FUNCTION match (l location_typ) RETURN INTEGER IS
BEGIN
IF self.building_no < l.building_no THEN
RETURN -1; -- qualquer número negativo
ELSIF self.building_no > l.building_no THEN
RETURN 1; -- qualquer número positivo
ELSE RETURN 0;
END IF;
END;
END;
Capítulo 4: BDOR – SGBD Oracle 11g 48
Evolução de Tipos
Uso do comando ALTER TYPE, permite modificar
ou evoluir um tipo objeto:
Adicionar e remover atributos
Adicionar e remover métodos
Modificar um atributo numérico para aumentar a precisão
ou a escala
Modificar um atributo texto para aumentar seu
comprimento
Mudar propriedades FINAL e INSTANTIABLE do tipo
Capítulo 4: BDOR – SGBD Oracle 11g 49
Evolução de Tipos
Exemplos
ALTER TYPE person_typ
ADD ATTRIBUTE (sex CHAR(1)) CASCADE;
ALTER TYPE person_typ
DROP MAP MEMBER FUNCTION get_id RETURN NUMBER;
ALTER TYPE person_typ NOT FINAL CASCADE;
ALTER TYPE person_typ FINAL; -- não poderá ter subtipo
Observação CASCADE: propaga a mudança para todos os tipos dependentes
Capítulo 4: BDOR – SGBD Oracle 11g 50
Evolução de Tipos – Exemplo 01CREATE TYPE address_type AS OBJECT (street VARCHAR2(60));
CREATE TABLE customer (
id NUMBER, name VARCHAR2(40), address address_type);
ALTER TYPE address_type ADD ATTRIBUTE province VARCHAR2(40);
*
ERRO na linha 1:
ORA-22312: é necessário especificar a opção CASCADE ou INVALIDATE
ALTER TYPE address_type ADD ATTRIBUTE province VARCHAR2(40) CASCADE;
SQL> DESCRIBE address_type
Nome Nulo? Tipo
----------------------------------------- -------- ------------
STREET VARCHAR2(60)
PROVINCE VARCHAR2(40)
Capítulo 4: BDOR – SGBD Oracle 11g 51
Evolução de Tipos – Exemplo 02CREATE TYPE address_type2 AS OBJECT (street VARCHAR2(60), num NUMBER);
CREATE OR REPLACE PROCEDURE test_proc01 IS
v_address ADDRESS_TYPE2;
BEGIN
v_address.street := 'test';
END;
SELECT status FROM user_objects WHERE object_name = 'TEST_PROC01';
STATUS
-------
VALID
ALTER TYPE address_type2 DROP ATTRIBUTE num INVALIDATE;
SELECT status FROM user_objects WHERE object_name = 'TEST_PROC01';
STATUS
-------
INVALID
Capítulo 4: BDOR – SGBD Oracle 11g 52
Herança de Tipos
Suporta herança simples
Há uma diferença do padrão SQL:1999, pois o Oraclenão requer herança explicitamente nas tabelas, mas apenas nos tipos modelo mais simples
Permite criar uma hierarquia de sub-tipos especializados
Os tipos derivados (sub-tipos) herdam os atributos e métodos dos tipos ancestrais (super-tipos)
Os sub-tipos podem acrescentar novos atributos ou métodos e/ou redefinir os métodos dos super-tipos
Princípio da Substituição (herança de tipos)
Uma coluna ou row definidas do tipo t podem conter
instâncias de quaisquer de seus subtipos
Capítulo 4: BDOR – SGBD Oracle 11g 53
Herança de Tipos
CREATE or replace TYPE person_typ AS
OBJECT (
idno NUMBER,
name VARCHAR2(30),
phone VARCHAR2(20),
FINAL MAP MEMBER FUNCTION get_idno
RETURN NUMBER
) NOT FINAL;
Obs.: Por default, um tipo de objeto é FINAL!
Capítulo 4: BDOR – SGBD Oracle 11g 54
Herança de Tipos
CREATE TYPE employee_typ UNDER person_typ (
depto_id NUMBER,
funcao VARCHAR2(30),
salario NUMBER
) NOT FINAL;
CREATE TYPE professor_typ UNDER person_typ (
dept_id NUMBER,
speciality VARCHAR2(30)
) NOT FINAL;
Capítulo 4: BDOR – SGBD Oracle 11g 55
Herança de Tipos
CREATE TYPE student_typ UNDER
person_typ (
registration NUMBER
) NOT FINAL;
CREATE TYPE monitor_typ UNDER
student_typ (
year NUMBER
) NOT FINAL;
Capítulo 4: BDOR – SGBD Oracle 11g 56
Herança de Tipos
SQL> DESCRIBE person_typ;
person_typ is NOT FINAL
Nome Nulo? Tipo
--------------------------------------- -------- ------------
IDNO NUMBER
NAME VARCHAR2(30)
PHONE VARCHAR2(20)
SQL> DESCRIBE employee_typ;
employee_typ extends HR.PERSON_TYP
employee_typ is NOT FINAL
Nome Nulo? Tipo
---------------------------------------- -------- ------------
IDNO NUMBER
NAME VARCHAR2(30)
PHONE VARCHAR2(20)
DEPTO_ID NUMBER
FUNCAO VARCHAR2(30)
SALARIO NUMBER
Capítulo 4: BDOR – SGBD Oracle 11g 57
Herança de Tipos
CREATE TABLE person_tab OF person_typ;
CREATE TABLE student_tab OF student_typ;
CREATE TABLE monitor_tab OF monitor_typ;
INSERT INTO person_tab VALUES (person_typ(1,'JOSE','88839098'));
INSERT INTO student_tab VALUES(student_typ(2,'MARIA', '33372298',20000));
INSERT INTO monitor_tab VALUES(monitor_typ(3, 'EICKMANN','33362288',30000,2010));
Não foi necessário usar
UNDER
Capítulo 4: BDOR – SGBD Oracle 11g 58
Herança de Tipos
SELECT p.*
FROM person_tab p;
IDNO NAME PHONE
---- ------------------------------ --------------------
1 JOSE 88839098
SELECTs.*
FROM student_tab s;
IDNO NAME PHONE REGISTRATION
---- ------------------------------ -------------------- ----------------------
2 MARIA 33372298 20000
SELECTm.*
FROM monitor_tab m;
IDNO NAME PHONE REGISTRATION YEAR
---- ------------------- -------------- ---------------------- -------
3 EICKMANN 33362288 30000 2010
Capítulo 4: BDOR – SGBD Oracle 11g 59
Herança de Tipos
DELETE FROM person_tab;
DELETE FROM student_tab;
DELETE FROM monitor_tab;
INSERT INTO person_tab VALUES
(person_typ(1,'JOSE','33378787'));
INSERT INTO person_tab VALUES
(student_typ(2,'MARIA','87637876',10000));
INSERT INTO person_tab VALUES
(monitor_typ(3,'PEDRO','33353987',20000,2010));
Princípio da
Substituição
Capítulo 4: BDOR – SGBD Oracle 11g 60
Herança de Tipos
SELECT p.*
FROM person_tab p;
IDNO NAME PHONE
---------- ----------- -------------
1 JOSE 33378787
2 MARIA 87637876
3 PEDRO 33353987
SELECT s.name
FROM student_tab s;
não há linhas selecionadas
Capítulo 4: BDOR – SGBD Oracle 11g 61
Herança de Tipos
INSERT INTO student_tab VALUES (student_typ(4,'MARY','22983376',40000));
SELECT s.name
FROM student_tab s;
NAME
------------
MARY
SELECT p.name FROM person_tab p
UNION
SELECT s.name FROM student_tab s;
NAME
------------
JOSE
MARIA
MARY
PEDRO
Capítulo 4: BDOR – SGBD Oracle 11g 62
Outro Exemplo de Herança
CREATE OR REPLACE TYPE emp_type AS OBJECT (
id NUMBER,
nm VARCHAR2(40))
NOT FINAL;
CREATE TYPE prof_type UNDER emp_type (
siape NUMBER);
CREATE TABLE emp_tab OF emp_type;
INSERT INTO emp_tab VALUES (prof_type(10,'JOSE',12345));
Capítulo 4: BDOR – SGBD Oracle 11g 63
Outro Exemplo de Herança
SELECT value(p) FROM emp_tab p;
VALUE(P)(ID, NM)
------------------------------------
PROF_TYPE(10, 'JOSE', 12345)
SELECT p.* FROM emp_tab p;
ID NM
--- -------------------
10 JOSE
Outro Exemplo de Herança
SELECT p.*,
TREAT(VALUE(p) as student_typ).registration
AS REGISTRATION_STU,
TREAT(VALUE(p) as monitor_typ).registration AS
REGISTRATION_MON
TREAT(VALUE(p) as monitor_typ).year AS
YEAR_MON
FROM person_tab p
/
Capítulo 4: BDOR – SGBD Oracle 11g 64
Capítulo 4: BDOR – SGBD Oracle 11g 65
Herança de Tipos – DROP TYPE
Não se pode remover um subtipo antes de
remover suas respectivas instâncias na tabela
que armazena as tuplas daquele subtipo
(substitutability)
Ex.: DROP TYPE student_typ VALIDATE;ORA-02303: não pode eliminar ou substituir um tipo com dependentes de tabela ou de tipo
Correto é:
TRUNCATE FROM student_tab;
DROP TABLE student_tab;
DROP TYPE student_typ VALIDATE;
Capítulo 4: BDOR – SGBD Oracle 11g 66
Overriding Method
CREATE TYPE person_typ AS OBJECT (
idno NUMBER,
name VARCHAR2(30),
phone VARCHAR2(20),
MAP MEMBER FUNCTION get_idno RETURN NUMBER,
STATIC FUNCTION show_super (person_obj IN person_typ) RETURN VARCHAR2,
MEMBER FUNCTION show RETURN VARCHAR2)
NOT FINAL;
Capítulo 4: BDOR – SGBD Oracle 11g 67
Overriding Method (cont.)CREATE TYPE BODY person_typ AS
MAP MEMBER FUNCTION get_idno RETURN NUMBER IS
BEGIN
RETURN idno;
END;
-- static function that can be called by subtypes
STATIC FUNCTION show_super (person_obj IN person_typ) RETURN VARCHAR2 IS
BEGIN
RETURN 'Id: ' || TO_CHAR(person_obj.idno) || ', Name: ' || person_obj.name;
END;
-- function that can be overriden by subtypes
MEMBER FUNCTION show RETURN VARCHAR2 IS
BEGIN
RETURN person_typ.show_super(SELF);
END;
END;
Capítulo 4: BDOR – SGBD Oracle 11g 68
Overriding Method (cont.)
CREATE TYPE student_typ UNDER person_typ (
dept_id NUMBER,
major VARCHAR2(30),
OVERRIDING MEMBER FUNCTION show RETURN VARCHAR2)
NOT FINAL;
CREATE TYPE BODY student_typ AS
OVERRIDING MEMBER FUNCTION show RETURN VARCHAR2 IS
BEGIN
RETURN person_typ.show_super(SELF) || ' -- Major: ' || self.major;
END;
END;
Capítulo 4: BDOR – SGBD Oracle 11g 69
Overriding Method (cont.)
CREATE TYPE employee_typ UNDER person_typ (
emp_id NUMBER,
mgr VARCHAR2(30),
OVERRIDING MEMBER FUNCTION show RETURN VARCHAR2);
CREATE TYPE BODY employee_typ AS
OVERRIDING MEMBER FUNCTION show RETURN VARCHAR2 IS
BEGIN
RETURN person_typ.show_super (SELF) || ' -- Employee Id: '
|| TO_CHAR(emp_id) || ', Manager: ' || mgr;
END;
END;
Capítulo 4: BDOR – SGBD Oracle 11g 70
Overriding Method (cont.)
CREATE TYPE part_time_student_typ UNDER student_typ (
number_hours NUMBER,
OVERRIDING MEMBER FUNCTION show RETURN VARCHAR2);
CREATE TYPE BODY part_time_student_typ AS
OVERRIDING MEMBER FUNCTION show RETURN VARCHAR2 IS
BEGIN
RETURN person_typ.show_super (SELF) || ' -- Major: ' || major || ', Hours: ' || TO_CHAR(number_hours);
END;
END;
Capítulo 4: BDOR – SGBD Oracle 11g 71
Overriding Method (cont.)
CREATE TABLE person_obj_table OF person_typ;
INSERT INTO person_obj_table
VALUES (person_typ(12, 'Bob Jones', '111-555-1212'));
INSERT INTO person_obj_table
VALUES (student_typ(51, 'Joe Lane', '1-800-555-1312', 12, 'HISTORY'));
INSERT INTO person_obj_table
VALUES (employee_typ(55, 'Jane Smith', '1-800-555-7765',
100, 'Jennifer Nelson'));
INSERT INTO person_obj_table
VALUES (part_time_student_typ(52, 'Kim Patel', '1-800-555-1232', 14, 'PHYSICS', 20));
Princípio da Substituição
Capítulo 4: BDOR – SGBD Oracle 11g 72
Overriding Method (cont.)
SELECT p.show() AS report
FROM person_obj_table p;
Resultado:
Id: 12, Name: Bob Jones
Id: 51, Name: Joe Lane -- Major: HISTORY
Id: 55, Name: Jane Smith -- Employee Id: 100, Manager:
Jennifer Nelson
Id: 52, Name: Kim Patel -- Major: PHYSICS, Hours: 20
Capítulo 4: BDOR – SGBD Oracle 11g 73
Restrições em Overriding Methods
Só se pode fazer overriding de métodos
declarados NOT FINAL no supertipo (default)
Métodos ORDER só podem ser definidos na raiz
da hierarquia de tipos, não podendo ser
overriden
Capítulo 4: BDOR – SGBD Oracle 11g 74
Tabelas no ORACLE 11g
Já vimos que o Oracle11g suporta pelo
menos 2 tipos de tabelas:
Tabela Relacional (tabela normal)
Tabela de Objetos (Object Table) Equivalentes às Tabelas Tipadas (Typed Tables)
do SQL:1999
Tipo especial de tabela que lida com objetos (“row
objects”) e fornece uma visão relacional dos
atributos desses objetos
Capítulo 4: BDOR – SGBD Oracle 11g 75
Tabela de Objetos vs. Tabela
Relacional
Uma tabela de objetos difere de uma tabela
relacional em vários aspectos:
Cada linha de uma tabela de objetos possui um
identificador de objeto (OID), definido pelo SGBD
ORACLE quando a linha é inserida na tabela
Um OID é um ponteiro para um objeto “linha” (ROW
Object)
As linhas (row objects) de uma tabela de objetos
podem ser referenciadas por outros objetos do banco
de dados
Capítulo 4: BDOR – SGBD Oracle 11g 76
Tabela de Objetos
A tabela de objetos PESSOAS pode ser vista como:
• Uma Tabela com uma única coluna
- cada linha é um objeto do tipo PESSOA_TY
• Uma Tabela com múltiplas colunas
- uma coluna para cada atributo do tipo PESSOA_TY
CREATE TYPE PESSOA_TY AS OBJECT
(Nome VARCHAR2(25),
CPF NUMBER,
Endereco ENDERECO_TY);
CREATE TABLE PESSOAS OF PESSOA_TY (CONSTRAINT
pessoa_cpf_pk PRIMARY KEY (cpf));
Capítulo 4: BDOR – SGBD Oracle 11g 77
Tabelas de Objetos
São tabelas especiais onde cada linha
armazena um objeto
Provê uma visão relacional desses objetos
As linhas de uma tabela de objetos possuem um
OID (Object IDentifier) implícito (definido pelo
ORACLE)
Os objetos de uma tabela de objetos podem ser
referenciados (REF) por outros objetos
Nos comandos de manipulação de objetos
deve-se utilizar aliases para as tabelas
Tabelas de Objeto
Derivando o OID a partir de uma coluna PK
CREATE TYPE employees_typ AS OBJECT
(e_no NUMBER,
e_address CHAR(30));
CREATE TABLE employees_obj_t OF
employees_typ (e_no PRIMARY KEY)
OBJECT IDENTIFIER IS PRIMARY KEY;
Capítulo 4: BDOR – SGBD Oracle 11g 78
Definindo Restrições de Integridade
CREATE TYPE address_t AS OBJECT (
hno NUMBER,
street VARCHAR2(40),
city VARCHAR2(20),
zip VARCHAR2(5),
phone VARCHAR2(10));
CREATE TYPE person AS OBJECT (
name VARCHAR2(40),
dateofbirth DATE,
homeaddress address_t);
CREATE TABLE persons OF person (
homeaddress NOT NULL,
UNIQUE (homeaddress.phone),
CHECK (homeaddress.zip IS NOT NULL),
CHECK (homeaddress.city <> 'San Francisco'));
Capítulo 4: BDOR – SGBD Oracle 11g 79
Definindo Restrições de Integridade
CREATE TYPE univ_typ AS OBJECT (cod NUMBER, univ VARCHAR2(10));
CREATE TYPE centro_typ AS OBJECT (cod NUMBER, centro VARCHAR2(10), univ univ_typ);
CREATE TYPE depto_typ AS OBJECT (cod NUMBER, depto VARCHAR2(10), centro
centro_typ);
CREATE TABLE inst (
cod NUMBER,
depto depto_type,
CONSTRAINT inst_pk PRIMARY KEY(depto.centro.univ.cod));
INSERT INTO inst VALUES (10,depto_typ(100,'DSC',centro_typ(1000,'CEEI',
univ_typ(10000,'UFCG'))));
Capítulo 4: BDOR – SGBD Oracle 11g 80
Capítulo 4: BDOR – SGBD Oracle 11g 81
SELECT p.* FROM pessoas p;
============================================================
NOME CPF ENDERECO(RUA, CIDADE, ESTADO, CEP)
--------------------- ---------------- ----------------------------------------------------------------
Maria Silva 543875432 ENDERECO_TY(‘Rua das Flores 84', ‘Campina
Grande', ‘PB', 58102324)
Seleção em PESSOAS como uma tabela de múltiplas
colunas:
INSERT INTO pessoas VALUES ('Maria Silva',543875432, ENDERECO_TY('Rua das Flores 84', 'Campina Grande', 'PB', '58102324'));
Seleção em Tabelas
Capítulo 4: BDOR – SGBD Oracle 11g 82
SELECT VALUE (p)
FROM PESSOAS p
WHERE p.nome = 'Maria Silva';
Resposta:
VALUE(P)(NOME, CPF, ENDERECO(RUA, CIDADE, ESTADO, CEP))
--------------------------------------------------------------------------------
PESSOA_TY(‘Maria Silva', 543875432, ENDERECO_TY(‘Rua das Flores 84',
‘Campina Grande', ‘PB', 58102324)
Seleção em PESSOAS como uma tabela de uma de
uma única coluna:
Seleção em Tabelas
Alias
Capítulo 4: BDOR – SGBD Oracle 11g 83
SELECT p.CPF
FROM PESSOAS p
WHERE p.nome = 'Maria Silva';
Resposta:
CPF
--------------------------------------------------------------
543875432
Seleção em Tabelas
Seleção em PESSOAS por coluna de tipo primitivo:
Capítulo 4: BDOR – SGBD Oracle 11g 84
SELECT p.endereco
FROM PESSOAS p
WHERE p.nome = 'Maria Silva';
Resposta:
ENDERECO(RUA, CIDADE, ESTADO, CEP)-------------------------------------------------------------
ENDERECO_TY('rua das Flores 84', ‘Campina Grande', ‘PB',
58102324)
Seleção em Tabelas
Seleção em PESSOAS por coluna de tipo de dados
definido pelo usuário:
Capítulo 4: BDOR – SGBD Oracle 11g 85
SELECT p.endereco.cidade, p.endereco.estado
FROM PESSOAS p
WHERE p.nome = 'Maria Silva';
Resposta:
ENDERECO.CIDADE ENDERECO.ESTADO
------------------------- ----------------------------
Campina Grande PB
Seleção em Tabelas
Seleção em PESSOAS por atributo de coluna cujo
tipo de dados é definido pelo usuário:
Capítulo 4: BDOR – SGBD Oracle 11g 86
Seleção em Tabelas
Seleção em PESSOAS pelo OID dos objetos:
SELECT REF(p)
FROM pessoas p
WHERE p.nome = 'Maria Silva';
Resposta:
REF(P)
--------------------------------------------------------------------------------------
000028020965E2D09F93B14F7795EBC4A77846A8237B6BF5CCEE8E455F9
43B79DF5CC491530240FD7E0000
-- Operador REF
Capítulo 4: BDOR – SGBD Oracle 11g 87
Inserção de Dados
CREATE TABLE person_obj_table OF person_typ;
INSERT INTO person_obj_table VALUES (
person_typ(101, 'John', 'Smith', '[email protected]', '1-800-555-1212') );
SET SERVEROUTPUT ON
DECLARE
v_person person_typ;
BEGIN -- PL/SQL block for selecting a person and displaying details
SELECT VALUE(p)
INTO v_person
FROM person_obj_table p
WHERE p.idno = 101;
person_typ.display_details(v_person); -- método estático
END;
Capítulo 4: BDOR – SGBD Oracle 11g 88
Inserção em PESSOAS como uma tabela de uma
única coluna.
- Usa o método construtor PESSOA_TY que constrói novos objetos
do tipo PESSOA_TY.
INSERT INTO PESSOAS VALUES
(PESSOA_TY(‘Maria Silva', 543875432,
ENDERECO_TY(‘Rua das Flores 84', ‘Campina Grande', ‘PB',
58102324)));
Métodos construtores para os tipos PESSOA_TY e
ENDERECO_TY. O nome do método construtor tem o
mesmo nome do tipo.
Inserção em Tabelas de Objetos
Capítulo 4: BDOR – SGBD Oracle 11g 89
Inserção Usando Substitutability
CREATE TABLE contacts (
contact person_typ,
contact_dateDATE );
INSERT INTO contacts
VALUES (person_typ (12, 'Bob Jones', '111-555-1212'), '24 Jun 2003' );
INSERT INTO contacts
VALUES (student_typ(51, 'Joe Lane', '1-800-555-1312', 12, 'HISTORY'), '24 Jun 2003' );
INSERT INTO contacts
VALUES (part_time_student_typ(52, 'Kim Patel', '1-800-555-1232', 14, 'PHYSICS', 20), '24 Jun 2003' );
Capítulo 4: BDOR – SGBD Oracle 11g 90
Desligando a Substitutability
CREATE TYPE office_typ AS OBJECT (
office_id VARCHAR(10),
location location_typ,
occupant person_typ)
NOT FINAL;
CREATE TABLE office_tab OF office_typ
COLUMN occupant NOT SUBSTITUTABLE AT ALL LEVELS;
Capítulo 4: BDOR – SGBD Oracle 11g 91
Desligando a Substitutability
Uma alternativa à cláusula: NOT
SUBSTITUTABLE AT ALL LEVELS é usar o
operador IS OF type, que especifica qual
subtipo pode ser instanciado
CREATE TABLE office_tab OF office_typ
COLUMN occupant IS OF (ONLY employee_typ);
Capítulo 4: BDOR – SGBD Oracle 11g 92
UPDATE PESSOAS p
SET p.endereco = ENDERECO_TY(‘Rua das Margaridas 23',
‘Patos', ‘PB', 58453230)
WHERE p.nome = ‘Maria Silva';
Atualização em Tabelas de Objetos
Atualiza endereço completo
UPDATE PESSOAS p
SET p.endereco.rua = ‘Rua das Margaridas 22'
WHERE p.nome = ‘Maria Silva';
Atualiza só a rua do endereço
Capítulo 4: BDOR – SGBD Oracle 11g 93
Remoção em Tabelas de Objetos
DELETE FROM PESSOAS p
WHERE p.nome = ‘Maria Silva';
Capítulo 4: BDOR – SGBD Oracle 11g 94
Identificadores de Objetos
Uma tabela de objetos contém uma coluna (implícita) gerada pelo SGBD contendo o OID do “row object”
OID de um objeto é único e imutável
Sobre essa coluna de OID é também criado automaticamente um índice para prover acesso eficiente sobre o objeto através do OID
A coluna de OID é equivalente a se ter uma coluna extra de 16 bytes para uma possível chave primária
Um OID permite que um “row object” seja referenciado em atributos de outros objetos ou em colunas de tabelas relacionais
Um tipo pré-definido REF é capaz de representar tais referências
Capítulo 4: BDOR – SGBD Oracle 11g 95
Referenciando Objetos (REF)
É um ponteiro lógico para um “Row Object”
Usado para fazer referência
É definido a partir do OID do objeto
Oferece acesso rápido/direto (índice)
Não garante integridade referencial
Para isso, tem que usar referential constraint
Neste caso, REF pode apontar para qualquer objeto
do tipo apontado
Capítulo 4: BDOR – SGBD Oracle 11g 96
REF – Exemplo 01
CREATE TYPE emp_person_typ AS OBJECT (
name VARCHAR2(30),
manager REF emp_person_typ);
CREATE TABLE emp_person_obj_table OF emp_person_typ;
INSERT INTO emp_person_obj_table VALUES (
emp_person_typ ('John Smith', NULL));
INSERT INTO emp_person_obj_table -- Insere Bob Jones apontando para John Smith
SELECT emp_person_typ('Bob Jones', REF(e))
FROM emp_person_obj_table e
WHERE e.name = 'John Smith';ou
INSERT INTO emp_person_obj_table VALUES ('Bob Jones',
(SELECT REF(e) FROM emp_person_obj_table e WHERE e.name
= 'John Smith'));
Capítulo 4: BDOR – SGBD Oracle 11g 97
REF – Exemplo 02CREATE OR REPLACE TYPE tp_cliente as OBJECT (
cod_cli VARCHAR2(3),
nome_cli VARCHAR2(60));
CREATE TABLE tb_cliente OF tp_cliente (
cod_cli CONSTRAINT tb_cliente_cod_cli_pk PRIMARY KEY,
nome_cli CONSTRAINT tp_cliente_nome_cli_nn NOT NULL);
CREATE OR REPLACE TYPE tp_dependente as OBJECT (
cod_dep VARCHAR2(3),
nm_dep VARCHAR2(60),
ref_titular REF tp_cliente);
CREATE TABLE tb_dependente OF tp_dependente (
cod_dep CONSTRAINT tb_dependente_cod_dep_pk PRIMARY KEY,
nm_dep CONSTRAINT tp_dependente_nm_dep_nn NOT NULL,
ref_titular SCOPE IS tb_cliente);
Capítulo 4: BDOR – SGBD Oracle 11g 98
REF – Exemplo 02
INSERT INTO tb_cliente VALUES ('C1', 'Rita');
INSERT INTO tb_cliente VALUES ('C2', 'Ana');
INSERT INTO tb_dependente
SELECT 'D1', 'Paulo', REF (c)
FROM tb_cliente c WHERE c.cod_cli = 'C1';
INSERT INTO tb_dependente
SELECT 'D2', 'Pedro', REF (c)
FROM tb_cliente c WHERE c.cod_cli = 'C2';
Capítulo 4: BDOR – SGBD Oracle 11g 99
REF
SELECT *
FROM tb_dependente;ou
SELECT d.*
FROM tb_dependente d;
COD_DEP NM_DEP REF_TITULAR
--------------------- --------------------- --------------------------------------------
D1 Paulo Q2459QW8RNDGS0D98G765SF
D2 Pedro 5XBGVX3B75XCN490VM0VBX4
OIDs de
clientes
Capítulo 4: BDOR – SGBD Oracle 11g 100
REF
SELECT REF(d)
FROM tb_dependente d
WHERE d. nm_dep = „Paulo‟;
REF(D)
----------------------------------------------
HRD23K56RNDGS0DUY6TGDE4
OID de
dependente
Capítulo 4: BDOR – SGBD Oracle 11g 101
REF
SELECT d.ref_titular.cod_cli AS cod_cliente,
d.ref_titular.nm_cli AS nm_cliente,
d.nm_dep AS nm_dependente
FROM tb_dependente d;
COD_CLIENTE NM_CLIENTE NM_DEPENDENTE
--------------------- ------------------- ---------------------
C1 Rita Paulo
C2 Ana Pedro
-- Não foi feita nenhuma operação de junção!
Capítulo 4: BDOR – SGBD Oracle 11g 102
Dangling REF
Verificando a validade das referências (Dangling)
DELETE FROM tb_cliente WHERE cod_cli = „C1‟;
Remove o “objeto Rita”SELECT d.ref_titular.cod_cli AS cod_cliente,
d.ref_titular.nm_cli AS nm_cliente,
d.nm_dep AS nm_dependente
FROM tb_dependente d;
COD_CLIENTE NM_CLIENTE NM_DEPENDENTE
---------------------------------------------------------------
Paulo
C2 Ana Pedro
O objeto Rita não é listado, mas Paulo ainda existe!!!!
Paulo aponta para um OID que não existe mais!
Capítulo 4: BDOR – SGBD Oracle 11g 103
Dangling REF
Verificando a validade das referências (Dangling)
SELECT d.ref_titular.cod_cli cod_cliente,
d.ref_titular.nome_cli nm_cliente,
d.nm_dep nm_dependente
FROM tb_dependente d
WHERE d.ref_titular IS DANGLING;
COD_CLIENTE NM_CLIENTE NM_DEPENDENTE
--------------------- ------------------- --------------------
Paulo
Capítulo 4: BDOR – SGBD Oracle 11g 104
Dangling REF
Verificando a validade das referências (Dangling)
SELECT d.ref_titular.cod_cli cod_cliente,
d.ref_titular.nome_cli nm_cliente,
d.nm_dep nm_dependente
FROM tb_dependente d
WHERE d.ref_titular IS NOT DANGLING; -- complemento
COD_CLIENTE NM_CLIENTE NM_DEPENDENTE
--------------------- ------------------- ----------------------
C2 Ana Pedro
Capítulo 4: BDOR – SGBD Oracle 11g 105
Dangling IS NOT NULL
SELECT d.ref_titular.cod_cli AS cod_cliente,
d.ref_titular.nm_cli AS nm_cliente,
d.nm_dep AS nm_dependente
FROM tb_dependente d
WHERE d.ref_titular IS NOT NULL;
COD_CLIENTE NM_CLIENTE NM_DEPENDENTE
--------------------- ------------------- --------------------
Paulo
C2 Ana Pedro
Capítulo 4: BDOR – SGBD Oracle 11g 106
SCOPED REF
CREATE TABLE contacts_ref (
contact_ref REF person_typ SCOPE IS person_obj_table,
contact_date DATE );
Para inserir uma linha na tabela contacts_ref:
INSERT INTO contacts_ref
SELECT REF(p), '26 Jun 2003'
FROM person_obj_table p
WHERE p.idno = 101;
Várias Object Tables podem ter
sido criadas a partir de
person_typ, nesse caso é bom
definir o escopo
Capítulo 4: BDOR – SGBD Oracle 11g 107
Integridade Referencial em REF
Vimos que apenas utilizar o tipo de dados REF
não garante integridade referencial
Utiliza-se uma sintaxe semelhante ao FOREIGN
KEY do modelo relacional
Exemplo: FOREIGN KEY (cust_ref)
REFERENCES customer_objtab
No exemplo acima o escopo é dado
implicitamente!
PRIMARY KEY não pode ser especificado para
uma coluna REF
Capítulo 4: BDOR – SGBD Oracle 11g 108
Integridade Referencial em REF
CREATE TYPE tipo_evento AS OBJECT (
codeve NUMBER,
nome VARCHAR2(500));
CREATE TYPE tipo_artigo AS OBJECT (
codart NUMBER,
titulo VARCHAR2(200),
evento REF tipo_evento);
CREATE TABLE tab_evento OF tipo_evento (
CONSTRAINT tab_evento_codeve_pk PRIMARY KEY (codeve));
CREATE TABLE tab_artigo OF tipo_artigo (
CONSTRAINT tab_artigo_codart_pk PRIMARY KEY (codart),
CONSTRAINT tab_artigo_evento_fk FOREIGN KEY (evento) REFERENCES
tab_evento);
EVENTO
ARTIGO
Capítulo 4: BDOR – SGBD Oracle 11g 109
Integridade Referencial em REF
INSERT INTO tab_evento VALUES (10,'ICDE');
1 linha criada.
INSERT INTO tab_artigo VALUES (1,'BLA BLA BLA',10);
ORA-00932: tipos de dados inconsistentes: esperava REF obteve NUMBER
INSERT INTO tab_artigo VALUES (1, 'BLA BLA BLA',(SELECT REF(e) FROM
tab_evento e WHERE e.codeve = 10));
1 linha criada.
DELETE FROM tab_evento WHERE codeve = 10;
ORA-02292: restrição de integridade (TPCE.TAB_ARTIGO_EVENTO_FK)
violada - registro filho localizado
Capítulo 4: BDOR – SGBD Oracle 11g 110
DEREF
O operador DEREF “desfaz” o REF
Retorna um objeto referenciado por uma coluna
do tipo REF
Desreferenciar um objeto dangling retorna um
objeto null
Capítulo 4: BDOR – SGBD Oracle 11g 111
DEREF
Exemplo
SELECT DEREF(d.ref_titular) AS deref_titular,
d.nm_dep AS nm_dependente
FROM tb_dependente d;
DEREF_TITULAR NM_DEPENDENTE
---------------------------------------------------- -------------------
TP_CLIENTE('C1', 'Rita') Paulo
TP_CLIENTE('C2', 'Ana') Pedro
Capítulo 4: BDOR – SGBD Oracle 11g 112
DEREF
Exemplo (sem usar DEREF)
SELECT d.ref_titular AS sem_deref,
d.nm_dep AS nm_dependente
FROM tb_dependente d;
SEM_DEREF NM_DEPENDENTE
------------------------------------------------------------------ --------------------------
P07XZC8V6Z0F97X6VZ965X6VZ4X8VXCVB6Z Paulo
XCVU6CHBD967B436CB74B5X9B2BX2VQ4WFF Pedro
Capítulo 4: BDOR – SGBD Oracle 11g 113
VALUE
Exibe os dados das instâncias dos objetos
Usa o mesmo formato que DEREF
Exemplo
SELECT VALUE(d) AS value_titular
FROM tb_dependente d;
VALUE_TITULAR (COD_DEP, NM_DEP, REF_TITULAR)
------------------------------------------------------------------------------------------
TP_DEPENDENTE('D1', 'Paulo', Q2459QW8RNDGS0D98G765SF)
TP_DEPENDENTE('D2', 'Pedro', 5XBGVX3B75XCN490VM0VBX4)
IS OF
CREATE TYPE person_t AS OBJECT (name
VARCHAR2(100), ssn NUMBER) NOT FINAL;
CREATE TYPE employee_t UNDER person_t
(department_id NUMBER, salary NUMBER) NOT FINAL;
CREATE TYPE part_time_emp_t UNDER employee_t
(num_hrs NUMBER); /
CREATE TABLE persons OF person_t;
SELECT *
FROM persons p
WHERE VALUE(p) IS OF TYPE (employee_t);
SELECT *
FROM persons p
WHERE VALUE(p) IS OF (ONLY person_t);Capítulo 4: BDOR – SGBD Oracle 11g 114
Capítulo 4: BDOR – SGBD Oracle 11g 115
EMPREGADO_TY DEPARTAMENTO_TYdepto
create table EMPREGADOS
(Nome VARCHAR2(25),
CPF NUMBER,
depto REF DEPARTAMENTO_TY SCOPE IS departamentos);
create type DEPARTAMENTO_TY as object
(Nome VARCHAR2(25),
... );
create table DEPARTAMENTOS of DEPARTAMENTO_TY
(
... );Os objetos do tipo DEPARTAMENTO_TY podem ser referenciados em colunas de tabelas relacionais ou em atributos de outros objetos.
Referenciando Objetos
Capítulo 4: BDOR – SGBD Oracle 11g 116
Um objeto do tipo REF encapsula uma referência para um “row object” de um tipo de objeto especificado
O valor de um objeto do tipo REF é um “ponteiro lógico” para um row object
REFs e coleções de REFs são utilizados na modelagem de associações entre objetos. Por exemplo, o relacionamento entre uma ordem de compra e um cliente
REFs constituem um mecanismo simples para navegar entre objetos. Pode-se utilizar a notação estendida de “pontos” para
seguir os ponteiros sem a necessidade de junções explícitas
create type EMPREGADO_TY as object
(Nome VARCHAR2(25),
CPF NUMBER,
depto REF DEPARTAMENTO_TY);
Tipo REF
Capítulo 4: BDOR – SGBD Oracle 11g 117
Coleções
O SGBD Oracle dá suporte a:
VARRAY: coleção ordenada de elementos, com
número fixo de elementos, se quiser manipular a
coleção toda de uma vez
Nested Tables (Tabelas Aninhadas): quando se
precisa executar consultas eficientes em coleções,
manipular um número arbitrário de elementos ou
executar várias operações de INSERT, UPDATE ou
DELETE
Capítulo 4: BDOR – SGBD Oracle 11g 118
VARRAYS
É um conjunto ordenado de elementos
Todos os elementos do VARRAY são do mesmo
tipo de dados (ou subtipo)
Cada elemento tem um índice, que representa
sua posição no array,e é usado para acessar
um dado elemento
Possui um número máximo de elementos,
chamado de tamanho do array (que pode ser
alterado depois)
Capítulo 4: BDOR – SGBD Oracle 11g 119
VARRAYS Exemplo 1: VARRAY de tipo de dados primitivo
CREATE TYPE email_list_arr AS VARRAY(10) OF VARCHAR2(80);
Exemplo 2: VARRAY de tipo de dados definido pelo usuário
CREATE TYPE phone_typ AS OBJECT (
country_code VARCHAR2(2),
area_code VARCHAR2(3),
ph_number VARCHAR2(7));
CREATE TYPE phone_varray_typ AS VARRAY(5) OF phone_typ;
CREATE TYPE dept_phone_type AS OBJECT (
dept_no NUMBER(5),
phone_list phone_varray_typ);
CREATE TABLE dept_phone_tab OF dept_phone_type;
INSERT INTO dept_phone_tab VALUES (
100,
phone_varray_typ( phone_typ ('01', '650', '5061111'),
phone_typ ('01', '650', '5062222'),
phone_typ ('01', '650', '5062525')));
Capítulo 4: BDOR – SGBD Oracle 11g 120
VARRAY
Modificando o tamanho de um elemento do
VARRAY
CREATE TYPE email_list_arr AS VARRAY(10) OF
VARCHAR2(80);
ALTER TYPE email_list_arr MODIFY ELEMENT
TYPE VARCHAR2(100) CASCADE;
Capítulo 4: BDOR – SGBD Oracle 11g 121
VARRAY
Modificando o tamanho do VARRAY
CREATE TYPE email_varray_typ AS VARRAY(5) OF email_list_typ;
ALTER TYPE email_varray_typ MODIFY LIMIT 100;
Métodos de VARRAY
COUNT: retorna a quantidade de elementos
DELETE: remove todos os elementos
EXISTS(n): determina se o elemento
especificado foi criado (retorna TRUE se o
elemento existe; FALSE, caso contrário)
TRIM(n): remove os últimos n elementos (o
valor default para n é 1)
EXTEND:
Capítulo 4: BDOR – SGBD Oracle 11g 122
Exemplo usando Métodos DECLARE
phone_nos phone_varray_typ;
cont INTEGER;
BEGIN
SELECT phone_list
INTO phone_nos
FROM dept_phone_tab
WHERE dept_no=100;
-- phone_nos := phone_varray_typ( phone_typ ('01', '650', '5061111'),
phone_typ ('01', '650', '5062222'),
phone_typ ('01', '650', '5062525'));
phone_nos.EXTEND(phone_nos.COUNT+1);
phone_nos(phone_nos.COUNT) := phone_typ ('01','650','5061111');
UPDATE dept_phone_tab
SET phone_list = phone_nos
WHERE dept_no = 100;
END;
/ Capítulo 4: BDOR – SGBD Oracle 11g 123
Capítulo 4: BDOR – SGBD Oracle 11g 124
Nested Table (Tabela Aninhada)
É um conjunto não ordenado de elementos,
cada um do mesmo tipo de dados
Não há número máximo de elementos e a
ordem não é preservada
Inserção, remoção, seleção e atualização
“como” em tabelas normais
Capítulo 4: BDOR – SGBD Oracle 11g 125
Nested Table (Exemplo)
CREATE TYPE person_typ AS OBJECT (
idno NUMBER,
name VARCHAR2(30),
phone VARCHAR2(25));
CREATE TYPE people_typ AS TABLE OF person_typ;
Capítulo 4: BDOR – SGBD Oracle 11g 126
Nested Table (Exemplo)
CREATE TABLE people_tab (
group_no NUMBER,
people_column people_typ)
NESTED TABLE people_column STORE AS people_column_nt;
INSERT INTO people_tab VALUES (
100,
people_typ (
person_typ (1, 'John Smith', '1-800-555-1212'),
person_typ (2, 'Diane Smith', NULL)
)
);
Pergunta:
O que fazer para transformar a tabela do slide
anterior de relacional para objeto-relacional,
mantendo a nested table?
Capítulo 4: BDOR – SGBD Oracle 11g 127
Capítulo 4: BDOR – SGBD Oracle 11g 128
Nested Table (Exemplo)CREATE TABLE students (
graduation DATE,
math_majors people_typ,
chem_majors people_typ,
physics_majors people_typ)
NESTED TABLE math_majors STORE AS math_majors_nt
NESTED TABLE chem_majors STORE AS chem_majors_nt
NESTED TABLE physics_majors STORE AS physics_majors_nt;
CREATE INDEX math_idno_idx ON math_majors_nt(idno);
CREATE INDEX chem_idno_idx ON chem_majors_nt(idno);
CREATE INDEX physics_idno_idx ON physics_majors_nt(idno);
INSERT INTO students (graduation) VALUES ('01-JUN-03');
UPDATE students
SET math_majors =
people_typ (person_typ(12, 'Bob Jones', '111-555-1212'),
person_typ(31, 'Sarah Chen', '111-555-2212'),
person_typ(45, 'Chris Woods', '111-555-1213')),
chem_majors =
people_typ (person_typ(51, 'Joe Lane', '111-555-1312'),
person_typ(31, 'Sarah Chen', '111-555-2212'),
person_typ(52, 'Kim Patel', '111-555-1232')),
physics_majors =
people_typ (person_typ(12, 'Bob Jones', '111-555-1212'),
person_typ(45, 'Chris Woods', '111-555-1213'))
WHERE graduation = '01-JUN-03';
Capítulo 4: BDOR – SGBD Oracle 11g 129
Nested Table (Exemplo)ou
INSERT INTO students VALUES ('01-JUN-03',
people_typ (person_typ(12,'Bob Jones','111-555-1212'),
person_typ(31, 'Sarah Chen', '111-555-2212'),
person_typ(45, 'Chris Woods', '111-555-1213')),
people_typ (person_typ(51, 'Joe Lane', '111-555-1312'),
person_typ(31, 'Sarah Chen', '111-555-2212'),
person_typ(52, 'Kim Patel', '111-555-1232')),
people_typ (person_typ(12, 'Bob Jones', '111-555-1212'),
person_typ(45, 'Chris Woods', '111-555-1213')));
Capítulo 4: BDOR – SGBD Oracle 11g 130
Coleções Multi-dimensionais
Podemos ter:
Nested table de nested table type
Nested table de VARRAY type
VARRAY de nested table type
VARRAY de VARRAY type
Nested table ou VARRAY de um UDT que
tem um atributo que é uma nested table ou
VARRAY type
Capítulo 4: BDOR – SGBD Oracle 11g 131
Coleções Multi-DimensionaisCREATE TYPE location_typ AS OBJECT (
location_id NUMBER(4),
street_address VARCHAR2(40),
postal_code VARCHAR2(12),
city VARCHAR2(30),
state_province VARCHAR2(25));
CREATE TYPE nt_location_typ AS TABLE OF location_typ;
CREATE TYPE country_typ AS OBJECT (
country_id CHAR(2),
country_name VARCHAR2(40),
locations nt_location_typ);
CREATE TYPE nt_country_typ AS TABLE OF country_typ;
CREATE TABLE region_tab (
region_id NUMBER,
region_name VARCHAR2(25),
countries nt_country_typ)
NESTED TABLE countries STORE AS nt_countries_tab
(NESTED TABLE locations STORE AS nt_locations_tab);
Location
Country
Region
Capítulo 4: BDOR – SGBD Oracle 11g 132
Coleções Multi-Dimensionais
region_id region_name countries
country_id country_name locations
location_id street_address postal_code city state_province
1 200 State Av. 78227 Long Beach CA
2 300 Hall Av. 21238 Los Angeles CA 200 USA
…
location_id street_address postal_code city state_province
1 Rua do Sol 58022-098 Recife PE
2 Rua da Lua 50098-092 Campina Grande PB
1 America
300 Brazil
…
location_id street_address postal_code city state_province
1 30 Scott Street 80222 London Null
2 85 Palm Street 76790 Leeds Null 400 England
…
location_id street_address postal_code City state_province
1 Bld Jourdan 48044 Paris Null
2 Bld 43778 Marseille Null
2 Europe
500 France
…
…
Capítulo 4: BDOR – SGBD Oracle 11g 133
Coleções Multi-Dimensionais
INSERT INTO region_tab
VALUES(1, 'Europe', nt_country_typ(
country_typ( 'IT', 'Italy', nt_location_typ (
location_typ(1000, '1297 Via Cola di Rie','00989','Roma', ''),
location_typ(1100, '93091 Calle della Testa','10934','Venice','') )),
country_typ( 'CH', 'Switzerland', nt_location_typ (
location_typ(2900, '20 Rue des Corps-Saints', '1730', 'Geneva', 'Geneve'),
location_typ(3000, 'Murtenstrasse 921', '3095', 'Bern', 'BE') )),
country_typ( 'UK', 'United Kingdom', nt_location_typ (
location_typ(2400, '8204 Arthur St', '', 'London', 'London'),
location_typ(2500, 'Mag Centre, Ox Science Park', 'OX9 9ZB', 'Oxford', 'Oxford'),
location_typ(2600, '9702 Chester Road', '93', 'Stretford','Manchester') )
)
)
);
E se o tipo da nested table mais interna
não possui atributo?
Use COLUMN_VALUE
CREATE TYPE phone AS TABLE OF NUMBER;
CREATE TYPE phone_list AS TABLE OF phone;
CREATE TABLE my_customers (
name VARCHAR2(25),
phone_numbers phone_list)
NESTED TABLE phone_numbers STORE AS outer_ntab
(NESTED TABLE COLUMN_VALUE STORE AS inner_ntab);
Capítulo 4: BDOR – SGBD Oracle 11g 134
Exercício de Sala
Criar o modelo lógico OR para o seguinte
modelo conceitual
Capítulo 4: BDOR – SGBD Oracle 11g 135
Aluno Professor
Área
2
A solução está nas anotações desse slide
Capítulo 4: BDOR – SGBD Oracle 11g 136
Operações em Coleções
CREATE TYPE people_typ AS TABLE OF person_typ;
CREATE TABLE department_persons (
dept_no NUMBER PRIMARY KEY,
dept_name CHAR(20),
dept_mgr person_typ DEFAULT person_typ(10,'John Doe',NULL),
dept_emps people_typ)
NESTED TABLE dept_emps STORE AS dept_emps_tab;
INSERT INTO department_persons VALUES ( 101, 'Physical Sciences', person_typ(65,'Vrinda Mills', '1-800-555-4412'), people_typ( person_typ(1, 'John Smith', '1-800-555-1212'), person_typ(2, 'Diane Smith', '1-800-555-1243') ) );
INSERT INTO department_persons VALUES ( 104, 'Life Sciences', person_typ(70,'James Hall', '1-800-555-4621'), people_typ(person_typ(3, 'Jorge Valdez', '1-800-555-9389') ));
Capítulo 4: BDOR – SGBD Oracle 11g 137
Operações em Coleções
Existem duas formas de se realizar uma
consulta em colunas com coleções:
Uma delas traz as coleções aninhadas dentro das
linhas que as contêm
A outra forma, desaninha (unnest) as coleções de
forma que cada elemento da coleção aparecerá numa
linha do resultado
Capítulo 4: BDOR – SGBD Oracle 11g 138
Operações em Coleções
Consultas com resultado aninhado:
SELECT d.dept_emps -- Dados da tabela aninhada
FROM department_persons d;
DEPT_EMPS(IDNO, NAME, PHONE)
----------------------------------------------------------------------------------------------------
PEOPLE_TYP(PERSON_TYP(1, 'John Smith', '1-800-555-1212'),
PERSON_TYP(2, 'Diane Smith', '1-800-555-12))
PEOPLE_TYP(PERSON_TYP(3, 'Jorge Valdez', '1-800-555-9389'))
Capítulo 4: BDOR – SGBD Oracle 11g 139
Consultas com resultado desaninhado:
SELECT e.* -- Dados da tabela aninhada
FROM department_persons d, TABLE(d.dept_emps) e;
IDNO NAME PHONE
-------- ----------------------------------- --------------
1 John Smith 1-800-555-1212
2 Diane Smith 1-800-555-1243
3 Jorge Valdez 1-800-555-9389
Operações em Coleções
Capítulo 4: BDOR – SGBD Oracle 11g 140
Consulta que resulta linhas de departamentos
que possuem empregados
SELECT d.dept_no, e.*
FROM department_persons d, TABLE(d.dept_emps) e;
DEPT_NO IDNO NAME PHONE
-------------- ---------- ------------------------------ ----------------------
101 1 John Smith 1-800-555-1212
101 2 Diane Smith 1-800-555-1243
104 3 Jorge Valdez 1-800-555-9389
Operações em Coleções
Capítulo 4: BDOR – SGBD Oracle 11g 141
Mesma consulta anterior mostrando também
departamentos sem empregados (outer join)
INSERT INTO department_persons VALUES ( 110, 'Mathematics',
person_typ(5, 'Dr Kumalo', '1-800-555-3312'),people_typ() );
SELECT d.dept_no, e.*
FROM department_persons d, TABLE(d.dept_emps) (+) e;
DEPT_NO IDNO NAME PHONE
--------------- ------------ ------------------------ --------------
110
104 3 Jorge Valdez 1-800-555-9389
101 1 John Smith 1-800-555-1212
101 2 Diane Smith 1-800-555-1243
Operações em Coleções
Capítulo 4: BDOR – SGBD Oracle 11g 142
SELECT *
FROM TABLE (
SELECT d.dept_emps
FROM department_persons d
WHERE d.dept_no = 101);
IDNO NAME PHONE
---- ------------------------------ --------------
1 John Smith 1-800-555-1212
2 Diane Smith 1-800-555-1243
Observações
A subquery acima deve retornar sempre uma coleção
A projeção da subquery deve conter apenas um item
Operações em Coleções
Capítulo 4: BDOR – SGBD Oracle 11g 143
Operações em Coleções
Inserção na tabela aninhada
INSERT INTO TABLE(SELECT d.dept_emps
FROM department_persons d
WHERE d.dept_no = 101) – deve retornar uma única linha
VALUES (5, 'Kevin Taylor', '1-800-555-6212');
Capítulo 4: BDOR – SGBD Oracle 11g 144
Operações em Coleções
Atualização
UPDATE TABLE(SELECT d.dept_emps
FROM department_persons d
WHERE d.dept_no = 101) e
SET VALUE(e) = person_typ(5, 'Kevin Taylor', '1-
800-555-6233')
WHERE e.idno = 5;
Capítulo 4: BDOR – SGBD Oracle 11g 145
Operações em Coleções
Remoção
DELETE FROM TABLE(SELECT d.dept_emps
FROM department_persons d
WHERE d.dept_no = 101) e
WHERE e.idno = 5
Capítulo 4: BDOR – SGBD Oracle 11g 146
Operações em Coleções
CREATE TYPE location_typ AS OBJECT (
location_id NUMBER(4),
street_address VARCHAR2(40),
postal_code VARCHAR2(12),
city VARCHAR2(30),
state_province VARCHAR2(25));
CREATE TYPE nt_location_typ AS TABLE OF location_typ;
CREATE TYPE country_typ AS OBJECT (
country_id CHAR(2),
country_name VARCHAR2(40),
locations nt_location_typ);
CREATE TYPE nt_country_typ AS TABLE OF country_typ;
CREATE TABLE region_tab (
region_id NUMBER,
region_name VARCHAR2(25),
countries nt_country_typ) NESTED TABLE countries STORE AS nt_countries_tab (NESTED TABLE locations STORE AS nt_locations_tab);
Capítulo 4: BDOR – SGBD Oracle 11g 147
Operações em Coleções
INSERT INTO region_tab VALUES(
1, 'Europe',
nt_country_typ (
country_typ( 'IT', 'Italy',
nt_location_typ (
location_typ(1000, '1297 Via Cola di Rie','00989','Roma', ''),
location_typ(1100, '93091 Calle della Testa','10934','Venice','') ) ),
country_typ( 'CH', 'Switzerland',
nt_location_typ (
location_typ(2900, '20 Rue des Corps-Saints', '1730', 'Geneva', 'Geneve'),
location_typ(3000, 'Murtenstrasse 921', '3095', 'Bern', 'BE') ) ),
country_typ( 'UK', 'United Kingdom',
nt_location_typ (
location_typ(2400, '8204 Arthur St', '', 'London', 'London'),location_typ(2500, 'Magdalen Centre, The Oxford Science Park', 'OX9
9ZB', 'Oxford', 'Oxford'),
location_typ(2600, '9702 Chester Road', '09629850293', 'Stretford', 'Manchester') ) ) ) );
Capítulo 4: BDOR – SGBD Oracle 11g 148
Consulta em Multi-Coleções
Exemplo 1
SELECT r.region_name, c.country_name, l.location_id
FROM region_tab r, TABLE(r.countries) c, TABLE(c.locations) l;
REGION_NAME COUNTRY_NAME LOCATION_ID
------------------------- --------------------------------------- --------------------
Europe Italy 1000
Europe Italy 1100
Europe Switzerland 2900
Europe Switzerland 3000
Europe United Kingdom 2400
Europe United Kingdom 2500
Europe United Kingdom 2600
Capítulo 4: BDOR – SGBD Oracle 11g 149
Consulta em Multi-Coleções
Exemplo 2
SELECT l.location_id, l.city
FROM region_tab r, TABLE(r.countries) c, TABLE(c.locations) l;
LOCATION_ID CITY
------------------- ---------
1000 Roma
1100 Venice
2900 Geneva
3000 Bern
2400 London
2500 Oxford
2600 Stretford
Capítulo 4: BDOR – SGBD Oracle 11g 150
Object Views
São tabelas de objetos (object table) virtuais
Cada linha (row) da Object View é um objeto,
podendo-se, portanto, chamar seus métodos e
acessar seus atributos
Dá um aspecto de classe a uma tabela
puramente relacional
Capítulo 4: BDOR – SGBD Oracle 11g 151
Criando uma Object View – Exemplo 1CREATE TABLE emp_table (
empnum NUMBER (5) PRIMARY KEY,
ename VARCHAR2 (20) NOT NULL,
salary NUMBER (9,2),
job VARCHAR2 (20));
CREATE TYPE employee_t AS OBJECT ( -- pode-se criar métodos aqui
empno NUMBER (5),
ename VARCHAR2 (20),
salary NUMBER (9,2),
job VARCHAR2 (20));
CREATE VIEW emp_view1 OF employee_t
WITH OBJECT IDENTIFIER (empno) AS
SELECT e.empnum, e.ename, e.salary, e.job
FROM emp_table e
WHERE e.job = 'Developer';
Capítulo 4: BDOR – SGBD Oracle 11g 152
Criando uma Object View – Exemplo 2CREATE TABLE dept (
deptno NUMBER PRIMARY KEY,
deptname VARCHAR2(20),
deptstreet VARCHAR2(20),
deptcity VARCHAR2(10),
deptstate CHAR(2),
deptzip VARCHAR2(10));
CREATE TYPE address_t AS OBJECT (
street VARCHAR2(20),
city VARCHAR2(10),
state CHAR(2),
zip VARCHAR2(10));
CREATE TYPE dept_t AS OBJECT (
deptno NUMBER,
deptname VARCHAR2(20),
address address_t );
CREATE VIEW dept_view OF dept_t WITH OBJECT IDENTIFIER (deptno) AS
SELECT d.deptno, d.deptname, address_t(d.deptstreet, d.deptcity, d.deptstate, d.deptzip) AS deptaddr
FROM dept d;
INSERT INTO dept_view VALUES (10, 'CS', address_t('20 Los Loucos','Long Beach','CA','62000'));