III – O Modelo OR Estudo de Caso, modelo Oracle9i

Preview:

Citation preview

IIII II – O Modelo OR– O Modelo OREstudo de Caso, modelo Estudo de Caso, modelo

Oracle9iOracle9i

Pedidos de CompraPedidos de CompraEsquema ConceitualEsquema Conceitual

Interface I-Endereco { attribute struct end {string rua, string cidade, string estado, string cep} endereco; }

Class Cliente : I-Endereco (extent Clientes key codigo) { attribute integer codigo; attribute string nome; attribute Array<string, 10> telefones }

Class Pedido : I-Endereco (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; 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 CompraPedidos de CompraEsquema Lógico OracleEsquema Lógico Oracle

Problemas a Resolver• Uma nova sintaxe

– Class ODL Type Oracle– Extent ODL Object Table Oracle– Oracle PL/SQL

• JSQL?• 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– Controle de acesso

• Resolvendo “deadlock”

– Tipos incompletos

CREATE TYPE StockItem_objtypCREATE TYPE LineItem_objtypCREATE 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

Controle de Acesso• WNDS

– Write No Database State• WNPS

– Write No Package State• RNDS

– Read No Database State• RNPS

– Read No Package State

Observação Importante• No Oracle, todo tipo é instanciável

instanciado• Se o tipo for instanciado

– Ele o será mais tarde• CREATE TABLE ... OF <type> ...

(<integriy constraints>)

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) )

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

Mais Transformação (Mapeamento)

• Relationship ODL REFerence Oracle

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

“Nested Table”

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 pelousuário

Objetos de umdos tipos primitivos*

Map()

*- INTEGER, NUMBER, DATE, CHAR e VARCHAR

CREATE TYPE StockItem_objtyp AS OBJECT ( StockNo NUMBER, Price NUMBER, TaxRate NUMBER )

• Definindo os Métodos

CREATE OR REPLACE TYPE BODY PurchaseOrder_objtyp ASMAP 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;

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”• ~1FN

– 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 SELECT 1001, REF(C),

SYSDATE, '10-MAY-1999', LineItemList_ntabtyp(), NULL

FROM Customer_objtab C WHERE C.CustNo = 1

INSERT INTO TABLE (SELECT P.LineItemList_ntab

FROM PurchaseOrder_objtab P WHERE P.PONo = 1001 )

SELECT 01, REF(S), 12, 0 FROM Stock_objtab S WHERE S.StockNo = 1004

• 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.ShipToAddr_obj, 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

Note que, essencialmente, SQLOR é como OQL, salvo algumas idiossincrasias da SQLOR

O valor total dos pedidos de compra

SELECT p.PONo, p.sumLineItems()FROM PurchaseOrder_objtab p

Pedidos do item 1004

SELECT po.PONo, po.Cust_ref.CustNo, L.* FROM PurchaseOrder_objtab po, TABLE

(po.LineItemList_ntab) LWHERE L.Stock_ref.StockNo = 1004

Qual é o problema com esta consulta?

• Destruindo objetos

DELETE FROM PurchaseOrder_objtab pWHERE p.PONo = 1001

Recommended