View
218
Download
3
Embed Size (px)
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