Sunteți pe pagina 1din 28

Características

Objeto Relacionales
en Oracle
Francisco Moreno
Universidad Nacional
Métodos Estáticos
 Un método estático no referencia a los
atributos del tipo
 Su comportamiento está determinado
por sus parámetros o por otros
elementos (distintos de los atributos
del tipo)
 La invocación de un método estático
se hace con el tipo NO con una
instancia de dicho tipo
Métodos Estáticos
CREATE OR REPLACE CREATE OR REPLACE
TYPE TYPE BODY matem_tip AS
matem_tip AS OBJECT STATIC FUNCTION
( factorial(n IN NUMBER)
cod VARCHAR(8), RETURN NUMBER IS
STATIC FUNCTION BEGIN
factorial(n IN NUMBER) IF n = 0 THEN RETURN 1;
RETURN NUMBER); ELSE RETURN
/ n * factorial(n-1);
END IF;
END factorial;
END;
/
Invocación
 Desde una consulta.

SELECT matem_tip.factorial(5)
Nótese que es el
FROM dual; tipo y no una
instancia la que
 Desde PL/SQL: invoca al método
estático
BEGIN
DBMS_OUTPUT.PUT_LINE(matem_tip.factorial(5));
END;
/
Métodos MAP y ORDER
 ¿Qué pasa si se comparan dos columnas
tipadas (objetos) con un operador como >?
Ej: empleado1 > empleado2
 Este problema también se presenta en
consultas que involucran objetos en una
cláusula:
ORDER BY objeto, GROUP BY objeto,
DISTINCT objeto
 Para solucionar este problema se debe crear un
método MAP u ORDER
Métodos MAP y ORDER
 Un tipo solo puede tener asociado uno de
estos métodos
 Son métodos miembros, no estáticos
 MAP suele tener mejor desempeño (tiempo
de ejecución) que ORDER pero puede ser
menos flexible ¿En qué sentido?
Métodos MAP y ORDER
 No soportan parámetros adicionales a los
preestablecidos  No se pueden
sobrecargar
 Son invocados implícitamente por las
operaciones que los requieren (ORDER,
GROUP BY,DISTINCT, >, etc.)
 Se pueden invocar explícitamente
 Pueden generar confusión en una cláusula
DISTINCT ya que “desaparecen” objetos
que aparentemente son distintos  Ver
ejemplos
Método MAP
 No tiene parámetros
 Es una función que debe retornar un
valor correspondiente a un tipo
primitivo del sistema (no puede retornar
objetos creados por el usuario)
Ejemplo
DROP TYPE emp_type FORCE;
CREATE OR REPLACE TYPE emp_type AS OBJECT(
cedula VARCHAR2(10),
nombre VARCHAR2(10),
edad NUMBER(2),
salario NUMBER (6),
MAP MEMBER FUNCTION ord_por_salario
RETURN NUMBER
Tipo primitivo
);
/
Implementación
CREATE OR REPLACE TYPE BODY emp_type
AS
MAP MEMBER FUNCTION ord_por_salario
RETURN NUMBER IS
BEGIN
RETURN salario;
END ord_por_salario;
END;
/
DROP TABLE emp;
CREATE TABLE emp OF emp_type
(cedula PRIMARY KEY, salario NOT NULL);

INSERT INTO emp VALUES('111', 'Bobaldo', 20, 100);


INSERT INTO emp VALUES('121', 'Dawn', 30, 200);
INSERT INTO emp VALUES('131', 'Lisa', 25, 80);
INSERT INTO emp VALUES('141', 'Sidhe', 21, 100);
INSERT INTO emp VALUES('151', 'Paddy', 21, 100);
INSERT INTO emp VALUES('171', 'Edneud', 18, 50);
Ahora ya es posible:

SELECT *
FROM emp e
ORDER BY VALUE(e);

CEDULA NOMBRE EDAD SALARIO


---------- ---------- ---------- ----------
171 Edneud 18 50
131 Lisa 25 80
111 Bobaldo 20 100
141 Sidhe 21 100 Empate (100)
151 Paddy 21 100
121 Dawn 30 200

Si hay empates en el valor retornado por la función MAP, el


orden entre los empatados es aleatorio
Considérese la consulta:

SELECT DISTINCT VALUE(e)


FROM emp e;

Resultado:
VALUE(E)(CEDULA, NOMBRE, EDAD, SALARIO, COMISION)
------------------------------------------------------------------------------------
EMP_TYPE('171', 'Edneud', 18, 50)
EMP_TYPE('131', 'Lisa', 25, 80)
EMP_TYPE('111', 'Bobaldo', 20, 100)
EMP_TYPE('121', 'Dawn', 30, 200)

¿Qué pasó con Sidhe y con Paddy?  Desaparición


Método ORDER
 Retorna un número (usualmente -1, 0, o 1)
 Recibe como parámetro un objeto del mismo tipo
al cual se le está creando la función ORDER
 En el método ORDER se comparan dos objetos (el
objeto invocador y el que llega como parámetro) y
se establece si el objeto invocador es <, = o > al
objeto parámetro (y se retorna un número negativo,
el cero o un número positivo, respectivamente)
 Cada objeto invocador se compara sucesivamente
con todos los objetos que llegan como parámetro
Ejemplo
DROP TYPE emp_type FORCE;
CREATE OR REPLACE TYPE emp_type AS OBJECT(
cedula VARCHAR2(10),
nombre VARCHAR2(10),
edad NUMBER(2),
salario NUMBER (6),
ORDER MEMBER FUNCTION ord_por_salario(a IN
emp_type)
RETURN NUMBER
);
/
CREATE OR REPLACE TYPE BODY emp_type AS
ORDER MEMBER FUNCTION ord_por_salario(a IN
emp_type)
RETURN NUMBER IS
BEGIN Esta operación
devolverá un
RETURN (salario - a.salario); número negativo,
END ord_por_salario; positivo o el cero

END;
/

Volver a crear la tabla emp, insertarle datos y


ensayar las dos consultas…
SELECT VALUE(e), COUNT(*) AS cuantos
FROM emp e
GROUP BY VALUE(e);

VALUE(e)(CEDULA, NOMBRE, EDAD, SALARIO) CUANTOS


--------------------------------------- -------
EMP_TYPE('171', 'Edneud', 18, 50) 1
EMP_TYPE('131', 'Lisa', 25, 80) 1
EMP_TYPE('111', 'Bobaldo', 20, 100) 3
EMP_TYPE('121', 'Dawn', 30, 200) 1
Vistas objeto
 Considere el siguiente modelo E-R

FACTURA compuesta
de DETALLE
#código
#pdto
fecha de *cant
Implementación relacional:

CREATE TABLE factura(


codigo NUMBER(8) PRIMARY KEY,
fecha DATE);

CREATE TABLE detalle(


pdto VARCHAR2(20),
codfac NUMBER(8) REFERENCES factura,
PRIMARY KEY(pdto, codfac),
cant NUMBER(8) NOT NULL CHECK (cant > 0)
);
INSERT INTO factura VALUES(1, SYSDATE);
INSERT INTO factura VALUES(2, SYSDATE-30);
INSERT INTO factura VALUES(3, SYSDATE+1);

INSERT INTO detalle VALUES('Leche’, 1, 100);


INSERT INTO detalle VALUES('Cerdo’, 1, 5);
INSERT INTO detalle VALUES('Cerdo’, 2, 10);

Convertir este modelo a objeto relacional sin


migrar los datos  Crear una capa virtual 
Vistas objeto
Procedimiento
Crear los tipos para las vistas objeto deseadas:

DROP TYPE fac_type FORCE;


CREATE TYPE fac_type AS OBJECT(
codigo NUMBER(8),
fecha DATE,
MEMBER FUNCTION total_det RETURN NUMBER);
/
CREATE OR REPLACE TYPE BODY fac_type AS
MEMBER FUNCTION total_det RETURN NUMBER IS
total_uni NUMBER(5);
BEGIN
SELECT NVL(SUM(cant),0) INTO total_uni
FROM detalle
WHERE codfac = codigo;
RETURN total_uni;
END total_det;
END;
/
DROP TYPE det_type FORCE;
CREATE TYPE det_type AS OBJECT(
pdto VARCHAR2(20),
codfac NUMBER(8),
cant NUMBER(8),
fac_ref REF fac_type
);
/
Se crean las vistas objeto:

CREATE OR REPLACE VIEW fobj OF fac_type


WITH OBJECT OID(codigo) AS
SELECT * FROM factura;

Campo en la vista, se corresponde


con el campo codigo de la tabla
factura
CREATE OR REPLACE VIEW detobj OF det_type
WITH OBJECT OID(pdto,codfac) AS
SELECT pdto, codfac, cant, Campos en la vista, se
corresponden
MAKE_REF(fobj, codfac) con (pdto y codfac) en la
FROM detalle; tabla detalle

Para cada valor de codfac se


obtiene un puntero desde la
vista fobj
Sintaxis:

MAKE_REF(view_name, value_list)

Donde:

 view_name: Vista objeto de la cual se desea derivar el


REF

 value_list: Lista de valores, separados por comas, los


cuales se deben acoplar con los atributos que
conforman el OID de la vista view_name.
Ya se puede trabajar con las vistas
objetos como si fueran tablas objetuales:

 SELECT * FROM fobj;


 SELECT f.codigo, f.total_det() AS total
FROM fobj f;
 SELECT d.codfac, d.pdto, d.fac_ref.fecha fec
FROM detobj d;
 SELECT d.codfac, d.pdto,
d.fac_ref.total_det() total
FROM detobj d;
Incluso se pueden insertar datos a través de la vista.
Los datos quedan en las tablas base (originales):

 INSERT INTO detobj(pdto, codfac, cant)


VALUES('Gallina’, 2, 1000);

S-ar putea să vă placă și