01/12/07 Seminario de Bases de Dat os 1 Características Objeto Características Objeto Relacionales en Oracle Relacionales en Oracle 10G* 10G* * Tomado del curso de Francisco Moreno
Jan 23, 2016
01/12/07 Seminario de Bases de Datos 1
Características Objeto Características Objeto Relacionales en Oracle Relacionales en Oracle 10G*10G*
* Tomado del curso de Francisco Moreno
01/12/07 Seminario de Bases de Datos 2
Colecciones
Las colecciones en Oracle son de 2 Tipos:
Tablas Anidadas (Nested Tables)
Varrays (Variable Arrays )
01/12/07 Seminario de Bases de Datos 3
Tablas Anidadas
La intersección de una fila y una columna puede contener una tabla
¿Violación a la primera forma normal? Álgebra y Cálculo para este tipo de
relaciones en:Roth, M.A.; Korth, H.F.; Silberschatz, A. "Extended Algebra and Calculus for ~1NF Relational Databases“, Reporte Técnico TR.85.19, Universidad de Texas, Austin, 1985.
01/12/07 Seminario de Bases de Datos 4
Primero se debe definir el tipotipo de la tabla anidada que desea crear
El tipo de datos de la tabla anidada puede estar basado en un tipo de datos: - Primitivo- Definido por el usuario (típicamente) - Incluso en el de otra tabla anidada
(tablas anidadas de tablas anidadas etc.)
01/12/07 Seminario de Bases de Datos 5
Cada tabla anidada puede contener un número ilimitado de filas
Son una alternativa para eliminar relaciones 1 a muchos haciendo en algunos casos más natural el diseño
El lenguaje para su manipulación puede resultar complejo
01/12/07 Seminario de Bases de Datos 6
EjemploModelo Entidad RelaciónModelo Entidad Relación
ORDENORDEN# id_orden# id_orden*fecha*fecha
DETALLE#id_producto *cantidad
en
compuesta de
Nota: La relación de orden a detalle podría ser obligatoria…
Veamos algunas alternativas para implementar este modelo
01/12/07 Seminario de Bases de Datos 7
RelacionalRelacional: 2 tablas y manejo de clave foránea
ORDEN# id_orden*fecha
DETALLEDETALLE#id_producto #id_producto #Id_orden (#Id_orden (cf))*cantidad*cantidad
Objeto relacionalObjeto relacional: Primera forma conPrimera forma con REFss:
-Crear los tipos para ORDEN y para DETALLE-Crear las tablas tipadas correspondientes-En el tipo DETALLE el atributo id_orden en vez de ser una claveforánea, se convierte en un REF que apunta hacia una tabla tipadade órdenes
01/12/07 Seminario de Bases de Datos 8
Objeto relacionalObjeto relacional: Segunda forma con tablas anidadasSegunda forma con tablas anidadas Se crea un tipo tabla anidada para manejar los
detalles Se crea una tabla “clásica” para manejar las órdenes
con columnas:- id_orden- fecha- detalles: La cual será una tabla anidada de detalles,
donde cada detalle consta de - id_producto - cantidad
01/12/07 Seminario de Bases de Datos 9
Gráficamente:
Junio 23 de 2002
78
Vacía Mayo 2 de 2003 34
Julio 13 de 2003 11
detallesdetallesfechafechaid_ordenid_orden
1001
902
cantidadcantidadid_productoid_producto
Tabla de ÓrdenesÓrdenes
1501
cantidadcantidadid_productoid_producto
01/12/07 Seminario de Bases de Datos 10
Se crea normalmente el tipo para los detalles:DROP TYPE detalle_tip FORCE;CREATE OR REPLACE TYPE detalle_tipAS OBJECT( id_producto NUMBER(3), cantidad NUMBER(10));/
01/12/07 Seminario de Bases de Datos 11
Se crea el tipo de la tabla anidada basada en el tipo detalle_tip :
CREATE OR REPLACE TYPEnest_detallenest_detalle AS TABLE OF detalle_tip;/ Un tipo de tabla anidada puede estar basado en
un tipo primitivo, por ejemplo:
CREATE OR REPLACE TYPE hobbies AS TABLE OF VARCHAR2(10);/
01/12/07 Seminario de Bases de Datos 12
Ahora ya es posible declarar la columna detalles de tipo nest_detallenest_detalle (tabla anidada de detalles):
DROP TABLE orden PURGE;CREATE TABLE orden ( id_orden NUMBER(3) PRIMARY KEY, fecha DATE NOT NULL, detalles detalles nest_detallenest_detalle)
NESTED TABLE detalles STORE AS store_detallesNESTED TABLE detalles STORE AS store_detalles;
¿Qué significa?
01/12/07 Seminario de Bases de Datos 13
detalles detalles es el nombre de la columna y contiene para cada orden su tabla anidada de detalles.
store_detalles store_detalles es el nombre físico del lugar (tabla) donde se almacenan todas todas las tablas anidadas de la columna detalles.Esta tabla no se puede accesar directamente*, sólo a través de la columna detallesdetalles. Directamente es “intocable”, sólo se puede describir…
* Aunque existe un HINT, que no se verá acá, que permite hacerlo…
01/12/07 Seminario de Bases de Datos 14
Inserción de datos
INSERT INTO orden VALUES(100,SYSDATE, nest_detalle( detalle_tip(10,1000),
detalle_tip(11,900), detalle_tip(17,200)) );
INSERT INTO orden VALUES(200,SYSDATE+1, nest_detalle( detalle_tip(10,2000),
detalle_tip(5,100), detalle_tip(13,220)) );
01/12/07 Seminario de Bases de Datos 15
Selección:
La selección es “normal”:
SELECT * FROM orden;
--Imprime cada orden acompañada de todos sus items…
SELECT detalles, id_orden FROM orden;
--Imprime el código de cada orden y sus detalles…
¿Qué pasa si se desea imprimir el código de cada orden sólo con el código de los productos de sus detalles? Ver más adelante
01/12/07 Seminario de Bases de Datos 16
Para agregar más detalles a la orden # 100, se requiere usar el operador TABLE, para acceder a la tabla anidada así:
INSERT INTO TABLETABLE (SELECT detalles FROM orden WHERE id_orden=100) VALUES(31,330);
INSERT INTO TABLE (SELECT detalles FROM orden WHERE id_orden=200) VALUES(32,30);
01/12/07 Seminario de Bases de Datos 17
Considérese lo siguiente:
DELETE orden;INSERT INTO orden VALUES(111,SYSDATE,NULL);
--Y ahora:
INSERT INTO TABLE (SELECT detalles FROM orden WHERE id_orden=111) VALUES(10,22);
--Genera el error:ORA-22908: reference to NULL table value¿Entonces cómo llenarla?
Tabla anidada nula
01/12/07 Seminario de Bases de Datos 18
Lo que se debe hacer es un update de la siguiente manera:
UPDATE orden SET detalles = nest_detalle ( detalle_tip(10,1000), detalle_tip(11,1100), detalle_tip(12,1200))WHERE id_orden = 111;
01/12/07 Seminario de Bases de Datos 19
Supóngase que se realiza lo siguiente:
DELETE FROM TABLE(SELECT detalles FROM orden WHERE id_orden=111);
Para insertar los detalles de la orden 111, se puede proceder* así:
INSERT INTO TABLE (SELECT detalles FROM orden WHERE id_orden=111) VALUES(10,2000);
Conclusión: Tabla anidada átomicamente nula ≠ Tabla anidada vacía
* En este caso el UPDATE también funciona
01/12/07 Seminario de Bases de Datos 20
Sumar 5 unidades a la cantidad de la orden 111 en su item 10:
UPDATE TABLE(SELECT detalles FROM orden WHERE id_orden=111) anidadaSET anidada.cantidad=anidada.cantidad + 5WHERE anidada.id_producto = 10;
El alias es opcional…
Borrar el item 10 a la orden 111:
DELETE FROM TABLE(SELECT detalles FROM orden WHERE id_orden=111)WHERE id_producto=10;
01/12/07 Seminario de Bases de Datos 21
Selección de columnas de la tabla anidada con columnas de la tabla que la contiene:
SELECT id_orden, t2.id_producto FROM orden t, TABLE(t.detalles) t2;
Desanidamiento
01/12/07 Seminario de Bases de Datos 22
Star#name #name *age*age
PlanetPlanet#name *mass
gobernando a
orbitando a
SatelliteSatellite#name#name*diameter*diameter
orbitando a
gobernando a
01/12/07 Seminario de Bases de Datos 23
DROP TYPE satellite_t FORCE;CREATE OR REPLACE TYPE satellite_t AS OBJECT ( name VARCHAR2(20), diameter NUMBER(10));/
DROP TYPE nt_sat_t FORCE;CREATE TYPE nt_sat_t AS TABLE OF satellite_t;/
01/12/07 Seminario de Bases de Datos 24
DROP TYPE planet_t FORCE;CREATE OR REPLACE TYPE planet_t AS OBJECT ( name VARCHAR2(20), mass NUMBER(10), satellites nt_sat_t);/
DROP TYPE nt_pl_t FORCE;CREATE TYPE nt_pl_t AS TABLE OF planet_t;/
01/12/07 Seminario de Bases de Datos 25
DROP TABLE star PURGE;CREATE TABLE star( name VARCHAR2(20), age NUMBER(10), planets nt_pl_t)NESTED TABLE planets STORE AS planets_tab(NESTED TABLE satellites STORE AS satellites_tab);
01/12/07 Seminario de Bases de Datos 26
INSERT INTO star VALUES('Sun',23,nt_pl_t( planet_t('Neptune',10, nt_sat_t( satellite_t('Proteus',67), satellite_t('Triton',82) ) ), planet_t('Jupiter',189, nt_sat_t( satellite_t('Callisto',97), satellite_t('Ganymede', 22) ) ) ));
¿Qué implicaciones tendría manejar una entidad llamada cuerpo_celeste y manejar subtipos?
01/12/07 Seminario de Bases de Datos 27
SELECT s.name sn, p.name pn,t.name tnFROM star s, TABLE(s.planets) p, TABLE(p.satellites) t;
SN PN TN------- ------------ ---------------Sun Neptune ProteusSun Neptune TritonSun Jupiter CallistoSun Jupiter Ganymede