370 likes | 491 Views
I II – O Modelo OR. Estudo de Caso, Oracle. Pedidos de Compra. Esquema Conceitual. Class Cliente (extent Clientes key codigo) { attribute integer codigo; attribute string nome; attribute Array<string, 10> telefones; attribute struct end {string rua,
E N D
III – O Modelo OR Estudo de Caso, Oracle
Pedidos de Compra Esquema Conceitual
Class Cliente (extent Clientes key codigo) { attribute integer codigo; attribute string nome; attribute Array<string, 10> telefones; attribute struct end {string rua, string cidade, string estado, string cep} endereco; }
Class Pedido (extent Pedidos key codigo) { attribute integer codigo; attribute date data_pedido; attribute date data_entrega; attribute List<struct linha{integer num_linha, integer quantidade, float desconto}> linhas; attribute Cliente::end endereco; relationship List<Produto> refere_se; relationship Cliente feito_por; float total() } Class Produto (extent Produtos key codigo) { attribute integer codigo; attribute float preco }
Pedidos de Compra Esquema Lógico Oracle
Problemas a Resolver • Uma nova sintaxe • Class ODL Type Oracle • Extent ODL Object Table Oracle • Oracle PL/SQL • Algumas coisas mudam • Oracle não oferece os tipos-coleção Array e List • Varray e Nested Table • Oracle não oferece o conceito de Interface, e nem de Estrutura • Abstract (Virtual) Type • Um tipo sem repositório (“default”)
Problemas a Resolver (2) • No mundo da implementação, temos que pensar em situações bem específicas • “Deadlock” de tipos • Tipos inter-dependentes • Corpos dos métodos • Ordenação de objetos
Resolvendo “deadlock” • Tipos incompletos CREATE TYPE StockItem_objtyp CREATE TYPE LineItem_objtyp CREATE TYPE PurchaseOrder_objtyp
Definindo ‘estruturas’ • Abstract Types CREATE TYPE PhoneList_vartyp AS VARRAY(10) OF VARCHAR2(20)
CREATE TYPE Address_objtyp AS OBJECT ( Street VARCHAR2(200), City VARCHAR2(200), State CHAR(2), Zip VARCHAR2(20) )
Ordenação de Objetos • Métodos de instância • ORDER • MAP
CREATE TYPE Customer_objtyp AS OBJECT ( CustNo NUMBER, CustName VARCHAR2(200), Address_obj Address_objtyp, PhoneList_var PhoneList_vartyp, ORDER MEMBER FUNCTION compareCustomers(x IN Customer_objtyp) RETURN INTEGER, PRAGMA RESTRICT_REFERENCES ( compareCustomers, WNDS, WNPS, RNPS, RNDS) ) Controle de acesso
Restrições ao Uso de Método ORDER • Deve retornar sempre um inteiro com sinal (INTEGER) • Deve ter 2 parâmetros de entrada • SELF • Um objeto X do mesmo tipo de SELF • A interpretação do Oracle é sempre • Positivo, SELF > X • Negativo, SELF < X • Zero, SELF = X • Em resumo, somente a lógica do método é da exclusividade do projetista do BD
“Nested Table” CREATE TYPE LineItem_objtyp AS OBJECT ( LineItemNo NUMBER, Stock_ref REF StockItem_objtyp, Quantity NUMBER, Discount NUMBER ) CREATE TYPE LineItemList_ntabtyp AS TABLE OF LineItem_objtyp Relationship ODL REFerence Oracle
CREATE TYPE PurchaseOrder_objtyp AS OBJECT ( PONo NUMBER, Cust_ref REF Customer_objtyp, OrderDate DATE, ShipDate DATE, LineItemList_ntab LineItemList_ntabtyp, ShipToAddr_obj Address_objtyp, MAP MEMBER FUNCTION getPONo RETURN NUMBER, PRAGMA RESTRICT_REFERENCES (getPONo, WNDS, WNPS, RNPS, RNDS), MEMBER FUNCTION sumLineItems RETURN NUMBER, PRAGMA RESTRICT_REFERENCES (sumLineItems, WNDS, WNPS) )
Funcionamento de MAP Objetos de tipo definido pelo usuário Objetos de um dos tipos primitivos* Map() *- INTEGER, NUMBER, DATE, CHAR e VARCHAR
CREATE TYPE StockItem_objtyp AS OBJECT ( StockNo NUMBER, Price NUMBER, TaxRate NUMBER )
CREATE OR REPLACE TYPE BODY PurchaseOrder_objtyp AS MAP MEMBER FUNCTION getPONo RETURN NUMBER is BEGIN RETURN PONo; END; MEMBER FUNCTION sumLineItems RETURN NUMBER IS Total NUMBER := 0; BEGIN SELECT SUM(L.Quantity * L.Stock_ref.Price) INTO Total FROM TABLE(CAST(SELF.LineItemList_ntab AS LineItemList_ntabtyp)) L; RETURN Total; END; END; • Definindo os Métodos
CREATE OR REPLACE TYPE BODY Customer_objtyp AS ORDER MEMBER FUNCTION compareCustomers (x IN Customer_objtyp) RETURN INTEGER IS BEGIN RETURN SELF.CustNo - x.CustNo; END; END;
Sobre “Object Tables” • Endereco é um tipo estruturado • ListaDeTelefones é uma coleção de elementos simples • LinhasDePedido é uma coleção de elementos estruturados • SQL precisa ser estendida para lidar com colunas não-atômicas
Sobre “Object Tables” (2) • Onde estão os métodos comuns aos objetos de uma “object table”? • Em um outro lugar (depende do SGBD específico) • O mais correto é entender uma “object table” como uma representação tabular ou relacional dos estados (i.e., valores dos atributos) dos objetos de um certo tipo
Criando as “Object Tables” CREATE TABLE Customer_objtab OF Customer_objtyp (PRIMARY KEY (CustNo)) CREATE TABLE Stock_objtab OF StockItem_objtyp (PRIMARY KEY (StockNo))
CREATE TABLE PurchaseOrder_objtab OF PurchaseOrder_objtyp (PRIMARY KEY (PONo), FOREIGN KEY (Cust_ref) REFERENCES Customer_objtab) NESTED TABLE LineItemList_ntab STORE AS PoLine_ntab ALTER TABLE PoLine_ntab ADD (SCOPE FOR (Stock_ref) IS stock_objtab)
Criando objetos INSERT INTO Stock_objtab VALUES(1004, 6750.00, 2) INSERT INTO Customer_objtab VALUES (1, 'Jean Nance', Address_objtyp('2 Avocet Drive', 'Redwood Shores', 'CA', '95054'), PhoneList_vartyp('415-555-1212') )
INSERT INTO PurchaseOrder_objtab VALUES( 1001, (SELECT REF(C) FROM Customer_objtab C WHERE C.CustNo = 1), SYSDATE, '10-MAY-1999', LineItemList_ntabtyp(), NULL );
INSERT INTO TABLE (SELECT P.LineItemList_ntab FROM PurchaseOrder_objtab P WHERE P.PONo = 1001 ) VALUES( 01, (SELECT REF(S) FROM STOCK_OBJTAB S WHERE S.STOCKNO = 1004), 12, 0 );
Consultando objetos Imprimir os números dos pedidos em ordem SELECT p.PONo FROM PurchaseOrder_objtab p ORDER BY VALUE(p)
Para o pedido 1, os detalhes SELECT p.Cust_ref.CustName, p.PONo, p.OrderDate, L.LineItemNo, L.Stock_ref.StockNo, L.Quantity FROM PurchaseOrder_objtab p, TABLE(p.LineItemList_ntab) L WHERE p.PONo = 1001;
O valor total dos pedidos de compra SELECT p.PONo, p.sumLineItems() FROM PurchaseOrder_objtab p
Destruindo objetos DELETE FROM PurchaseOrder_objtab p WHERE p.PONo = 1001
Exercicio 1-Criando Objetos • Inserir um StockItem (na tabela StockItem_objtab) • Inserir um Custome (na tabela Customer_objtab) Coloque mais de um telefone na lista de telefones • Inserir um PurchaseOrder (na tabela PurchaseOrder_objtab) • Inserir valores na tabela LineItem_ntab do Pedido (PurchaseOrder) criado anteriormente • Imprimir os detalhes de todos os pedidos • Imprimir o numero e o valor total dos pedidos de compra
Exercício 2 • No esquema criado nos exercícios das aulas anteriores: • Criar um novo tipo Lista de Telefones, que é um conjunto de varchar. • Criar um tipo Estrela com os atributos: • noEstrela int, • nome char(30), • endereco endereco_type, • telefones lista_telefones_vartyp
Exercício 2 • Criar uma tabela para o tipo estrela_type • Alterar o tipo filme adicionando um atributo cujos valores sejam tabelas aninhadas de referências para estrelas. • Inserir em tabela de estrelas os valores: • No estrela: 01, • Nome: 'Bel Marques', • Endereço: • Rua: 'Rua da Folia', • Número: 10, • Cidade: 'Salvador'), • Telefones: 3222-0555, 3412-2020, 8867-6547)
Exercício 2 • Inserir na tabela estrelas os valores: • noEstrela: 03, • Nome: Alceu Valenca • Endereço: • Rua: 'Rua da Folia', • Número: 10, • Cidade: 'Olinda', • Telefones: 3041-4150
Exercício 2 • Inserir um novo filme com os seguintes valores de atributos: • Nome: 'Carnaval de Pernambuco', • Estúdio: Referência para o estúdio de nome 'Ilha do Retiro'), • Duração: 200, • Chamar construtor default da tabela aninhada de estrelas.
Exercício 2 • Na tabela aninhada de estrelas do filme Carnaval de Pernambuco adicionar as estrelas criadas anteriormente. • Fazer um consulta que retorne o nome dos filmes e de suas estrelas. select f.nome, e.COLUMN_VALUE.nome from filmes f, table(f.estrelas)e; Basicamente a mesma query do exemplo, exceto pelo uso de COLUMN_VALUE para se referir à coluna da tabela aninhada