características objeto relacionales en oracle
DESCRIPTION
Características Objeto Relacionales en Oracle. Francisco Moreno Universidad Nacional. Métodos. Son de dos tipos: Procedimientos Funciones Los procedimientos y funciones se pueden invocar desde otros procedimientos o desde otras funciones. - PowerPoint PPT PresentationTRANSCRIPT
Características Características Objeto Relacionales Objeto Relacionales en Oracleen Oracle
Francisco Moreno
Universidad Nacional
MétodosSon de dos tipos:
• Procedimientos• Funciones
- Los procedimientos y funciones se pueden invocar desde otros procedimientos o desde otras funciones.
- Las funciones también se pueden invocar desde operaciones DML (pero los procedimientos no).
idlibroidlibro títulotítulo cantidadcantidad precio_baseprecio_base imp_baseimp_base génerogénero
LIBROLIBRO
impuesto()descuento(tiquete)
Atributos
Métodos
Sea
Ejemplo:
Para determinar el precio final de un libro se
considera un impuesto y un descuento .
El impuesto se obtiene del precio
base del libro así:
(imp_base + 5%) si hay menos de 100 unidades del libro
(imp_base + 10%) si hay más de 99 unidades del libro
Estos datos se guardan en una tabla así:
DROP TABLE rangoimp;CREATE TABLE rangoimp(liminf NUMBER(8) PRIMARY KEY,limsup NUMBER(8) UNIQUE NOT NULL,impto NUMBER(8),CHECK (liminf < limsup));
INSERT INTO rangoimp VALUES(0,99,5);INSERT INTO rangoimp VALUES(100,1000000,10);
El descuento se obtiene del precio base del
libro a partir de un tiquete que el cliente puede
presentar, así:
Tiquete tipo 1 descuento del 5% Tiquete tipo 2 descuento del 7.5% Tiquete tipo 3 descuento del 10% Sin tiquete descuento del 0%
Estos datos se guardan en una tabla así:
DROP TABLE dtiq;CREATE TABLE dtiq(cod NUMBER(1) PRIMARY KEY,val NUMBER(3,1) NOT NULL);
INSERT INTO dtiq VALUES(1,5);INSERT INTO dtiq VALUES(2,7.5);INSERT INTO dtiq VALUES(3,10);
CREATE OR REPLACE TYPE libro_tip AS OBJECT(--Atributos idlibroidlibro NUMBER(5), titulotitulo VARCHAR2(30), cantidadcantidad NUMBER(4), precio_baseprecio_base NUMBER(6), imp_base imp_base NUMBER(3), generogenero VARCHAR2(20),--Métodos: MEMBER FUNCTION impuesto RETURN
NUMBER, MEMBER FUNCTION descuentodescuento(tiquete IN
NUMBER) RETURN NUMBER);/
Notas: Los nombres de los métodos deben ser diferentes a los nombres de los atributos. Se permite sobrecarga de métodos y constructores de usuario, se ven más adelante
CREATE OR REPLACE TYPE BODYBODY libro_tip ASMEMBER FUNCTION impuesto RETURN
NUMBER ISi NUMBER(8);BEGINSELECT ((imp_base + impto) * precio_base)/100
INTO iFROM rangoimpWHERE cantidad BETWEEN liminf AND limsup;RETURN i;EXCEPTIONWHEN OTHERS THEN RETURN ((imp_base) * precio_base)/100; END impuesto; Nota: El body continúa en Nota: El body continúa en
la próxima diapositivala próxima diapositivaSi hay error solo se aplica el impuesto base
Atributos del objeto
Columna de rangoimp
MEMBER FUNCTION descuentodescuento(tiquete IN NUMBER)
RETURN NUMBER ISd NUMBER(8,2);BEGINSELECT (precio_base * val)/100 INTO dFROM dtiqWHERE cod = tiquete;RETURN d;EXCEPTIONWHEN OTHERS THEN RETURN 0; END descuentodescuento; END; --Fin del BODY/
Parámetro
Atributo del objeto
Columna de dtiq
Tabla tipada de libros:
DROP TABLE libro;CREATE TABLE libro OF libro_tip(idlibro PRIMARY KEY);INSERT INTO libro VALUES (libro_tiplibro_tip(785,'Billy el Mico',200,5000,5,'Novela'));INSERT INTO libro VALUES (libro_tiplibro_tip(795,'Beauty Disrupted',100,50000,5,'Biografía'));
Al insertar en una tabla tipada no es necesario invocar al constructor explícitamente:
INSERT INTO libro VALUES(523,'Azul',25,10000,10,'Poesía');INSERT INTO libro
VALUES(655,'Versos',70,15000,10,'Poesía');INSERT INTO libro
VALUES(625,'Dragón',700,5000,8,'Novela');
Ahora ya se pueden formular consultas como:
Imprimir el código de cada libro, su precio base,
su impuesto y su descuento con tiquete 1:
SELECT idlibro, titulo, precio_base, l.descuento(1) AS descuento, l.impuesto() AS impuestoFROM libro l;
¿Qué hacen las siguientes consultas?
a)
SELECT idlibro, titulo, precio_base, (l.precio_base - l.descuento(1) + l.impuesto()) AS precio_finalFROM libro l;
b)
SELECT idlibro, tituloFROM libro lWHERE (l.precio_base - l.descuento(2)
+ l.impuesto()) <= 10000;
c)
SELECT genero, COUNT(*) AS cuantos, SUM(precio_base) AS total_basico, SUM(precio_base - l.descuento(0) +
l.impuesto()) AS total_finalFROM libro lGROUP BY generoHAVING COUNT(*) > 1;
Supóngase que el precio finalprecio final de un libro se requiere constantemente…
Se puede crear una función llamada precio_final la cual invoca a las otras dos funciones para obtener el valor final del libro
ALTER TYPE libro_tipADD MEMBER FUNCTION
precio_final (tiquete IN NUMBER) RETURN
NUMBER CASCADE;
Ver otras opciones de modificación de
tipos más adelante Evolución de
tipos
Se debe crear de nuevo todo el BODY agregando el siguiente código:
MEMBER FUNCTION precio_finalprecio_final(tiquete IN NUMBER) RETURN NUMBER ISBEGIN RETURN (precio_base - descuento(tiquete)
+ impuesto);END precio_finalprecio_final; Acá no
requiere ()
Ahora ya es posible:
SELECT titulo, l.precio_final(1) AS pfinalFROM libro lWHERE l.precio_final(1) > 10000;
NotasNotas: Todavía se pueden invocar a las funciones
descuento e impuesto y cada una se puede alterar independientemente …
La función precio_final oculta todo el proceso del descuento y del impuesto
Un ejemplo con recursividad:Árboles Binarios
CREATE OR REPLACE TYPE nodo_tipo AS OBJECT(
izq REF nodo_tipo,dato NUMBER(5),der REF nodo_tipo, MEMBER FUNCTION inorden RETURN
VARCHAR);/
CREATE TABLE nodo OF nodo_tipo(dato PRIMARY KEY);
CREATE OR REPLACE TYPE BODY nodo_tipo AS MEMBER FUNCTION inorden RETURN VARCHAR AS in_izq VARCHAR2(100); in_der VARCHAR2(100); BEGIN IF izq IS NOT NULL THEN SELECT n.inorden() INTO in_izq FROM nodo n WHERE REF(n) = SELF.izq; END IF; IF der IS NOT NULL THEN SELECT n.inorden() INTO in_der FROM nodo n WHERE REF(n) = SELF.der; END IF; RETURN in_izq || ' ' || dato || in_der;END;END;/
Desafortunadamente, lo siguiente es inválido en PL/SQL: in_izq := izq.inorden(); o in_izq := SELF.izq.inorden();
Por eso se requiere el SELECT … INTO…que debería ser innecesario…
Sea el árbol:
731722721
7372
7
Primero se insertan las hojas 721, 722 y 731:
INSERT INTO nodo VALUES(NULL, 721721, NULL);INSERT INTO nodo VALUES(NULL, 722722, NULL);INSERT INTO nodo VALUES(NULL, 731731, NULL);
Ahora las subraíces 72 y 73:
INSERT INTO nodo VALUES((SELECT REF(n) FROM nodo n WHERE dato =
721), 7272, (SELECT REF(n) FROM nodo n WHERE dato = 722));
INSERT INTO nodo VALUES(NULL, 7373, (SELECT REF(n) FROM nodo n WHERE dato = 731));
--Ahora la raíz:
INSERT INTO nodo VALUES((SELECT REF(n) FROM nodo n WHERE dato =
72), 77, (SELECT REF(n) FROM nodo n WHERE dato = 73));
Finalmente, la consulta:
SELECT n.dato, n.inorden() AS rec_inordenFROM nodo n;
¿Qué pasa si se borra la tupla apuntada por un puntero?
DELETE FROM nodo WHERE dato = 731;
SELECT n.der.dato FROM nodo n WHERE dato = 73; SELECT dato FROM nodo
WHERE der IS DANGLING;
Se podría prevenir con un trigger…