13.08.2013 Views

Modelo objeto-relacional en Oracle ÍNDICE

Modelo objeto-relacional en Oracle ÍNDICE

Modelo objeto-relacional en Oracle ÍNDICE

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>Modelo</strong> <strong>objeto</strong>-<strong>relacional</strong> <strong>en</strong><br />

<strong>Oracle</strong><br />

<strong>Modelo</strong>s Avanzados de Bases de<br />

Datos<br />

Práctica 2<br />

<strong>ÍNDICE</strong><br />

• LOBS<br />

• TIPOS ANY<br />

• TIPOS DEFINIDOS POR EL USUARIO<br />

– TIPOS DISTINTOS<br />

– TIPOS ESTRUCTURADOS<br />

– TIPOS REF<br />

– MÉTODOS<br />

– HERENCIA<br />

– TIPOS COLECCIÓN: NESTED TABLES Y VARRAYS<br />

– EVOLUCIÓN DE TIPOS<br />

1


<strong>ÍNDICE</strong><br />

• LOBS<br />

• TIPOS ANY<br />

• TIPOS DEFINIDOS POR EL USUARIO<br />

– TIPOS DISTINTOS<br />

– TIPOS ESTRUCTURADOS<br />

– TIPOS REF<br />

– MÉTODOS<br />

– HERENCIA<br />

– TIPOS COLECCIÓN: NESTED TABLES Y VARRAYS<br />

– EVOLUCIÓN DE TIPOS<br />

LOBS<br />

• El tipo de datos predefinido LOB (Large<br />

OBjects) permite manejar las necesidades de<br />

almac<strong>en</strong>ami<strong>en</strong>to de imág<strong>en</strong>es, videos,<br />

docum<strong>en</strong>tos y <strong>en</strong> g<strong>en</strong>eral, cualquier tipo de dato<br />

no estructurado y de tamaño grande.<br />

• Los datos no estructurados no se pued<strong>en</strong><br />

descomponer <strong>en</strong> unidades de información más<br />

pequeñas y manejables.<br />

• Los datos multimedia probablem<strong>en</strong>te ocupe<br />

miles de veces ese espacio. Por ello, con el fin<br />

de minimizar el espacio de almac<strong>en</strong>ami<strong>en</strong>to <strong>en</strong><br />

la BD<br />

2


LOBS<br />

• G<strong>en</strong>eralm<strong>en</strong>te la información recogida por un LOB se<br />

guardará <strong>en</strong> ficheros que serán manejados por el<br />

sistema de ficheros del sistema operativo<br />

• En el campo correspondi<strong>en</strong>te al valor de tipo LOB habrá<br />

un puntero que permitirá acceder al cont<strong>en</strong>ido de dicho<br />

fichero.<br />

• <strong>Oracle</strong> puede almac<strong>en</strong>ar <strong>en</strong> la misma tabla LOBs<br />

pequeños, de hasta 4K de tamaño. Cuando el LOB<br />

supera ese tamaño, el SGBD lo almac<strong>en</strong>a fuera de la<br />

tablay pone <strong>en</strong> su lugar el localizador que permita<br />

acceder a la nueva ubicación de los datos.<br />

• Así, los LOBs son capaces de almac<strong>en</strong>ar hasta 4G de<br />

datos; además, se pued<strong>en</strong> definir varias columnas de<br />

tipo LOB <strong>en</strong> una misma tabla, así como varios atributos<br />

de un tipo de <strong>objeto</strong> pued<strong>en</strong> ser de tipo LOB.<br />

LOBS<br />

• Los LOBs se divid<strong>en</strong> básicam<strong>en</strong>te <strong>en</strong> dos<br />

subtipos:<br />

– INTERNOS: aquellos que se almac<strong>en</strong>an <strong>en</strong> los<br />

espacios de tabla (tablespaces) de la propia BD:<br />

BLOB (Binary Large OBjects), compuestos de datos<br />

binarios no estructurados, y los CLOB (Character<br />

Large OBjects) y NCLOB (National Character Large<br />

OBjects), que almac<strong>en</strong>an datos de tipo carácter;<br />

– EXTERNOS: los que almac<strong>en</strong>a el sistema de ficheros<br />

del sistema operativo. Los únicos LOBs externos son<br />

los BFILEs, que son grandes cantidades de datos<br />

binarios. Una columna o un atributo de tipo BFILE<br />

almac<strong>en</strong>a un puntero al comi<strong>en</strong>zo del fichero que<br />

conti<strong>en</strong>e los datos.<br />

3


• Ejemplo:<br />

LOBS<br />

CREATE TABLE Plano<br />

( planoID INTEGER PRIMARY KEY,<br />

fecha_fin DATE,<br />

gráfico BFILE);<br />

<strong>ÍNDICE</strong><br />

• LOBS<br />

• TIPOS ANY<br />

• TIPOS DEFINIDOS POR EL USUARIO<br />

– TIPOS DISTINTOS<br />

– TIPOS ESTRUCTURADOS<br />

– TIPOS REF<br />

– MÉTODOS<br />

– HERENCIA<br />

– TIPOS COLECCIÓN: NESTED TABLES Y VARRAYS<br />

– EVOLUCIÓN DE TIPOS<br />

4


TIPOS ANY<br />

• <strong>Oracle</strong> permite crear variables y columnas que<br />

pued<strong>en</strong> almac<strong>en</strong>ar datos de cualquier tipo,<br />

permiti<strong>en</strong>do comprobar el valor de ese dato <strong>en</strong><br />

cualquier mom<strong>en</strong>to;<br />

• De este modo se puede ver su repres<strong>en</strong>tación<br />

subyac<strong>en</strong>te, es decir, el tipo concreto del dato.<br />

• Empleando este tipo de datos, una misma<br />

columna puede almac<strong>en</strong>ar <strong>en</strong> una fila un valor<br />

numérico, <strong>en</strong> otra fila una cad<strong>en</strong>a de caracteres<br />

y <strong>en</strong> otra un <strong>objeto</strong>.<br />

TIPOS ANY<br />

• Exist<strong>en</strong> tres tipos de datos que permit<strong>en</strong> el<br />

tipado dinámico:<br />

– SYS.ANYDATA, que almac<strong>en</strong>a un valor de<br />

cualquier tipo escalar o tipo de <strong>objeto</strong>,<br />

– SYS.ANYDATASET, que almac<strong>en</strong>a valores<br />

de cualquier tipo colección y finalm<strong>en</strong>te, el<br />

– SYS.ANYTYPE que permite manipular y<br />

comprobar información de tipos.<br />

5


• Ejemplo<br />

CREATE TABLE tabla<br />

(un_valor SYS.AnyData);<br />

TIPOS ANY<br />

INSERT INTO tabla<br />

VALUES (SYS.AnyData.ConvertNumber(5));<br />

CREATE TYPE tipoEmpleado AS OBJECT(<br />

numE INTEGER,<br />

nombre VARCHAR (20))<br />

/<br />

INSERT INTO tabla<br />

VALUES (SYS.AnyData.ConvertObject(tipoEmpleado(5555,<br />

‘Pepe’)));<br />

<strong>ÍNDICE</strong><br />

• LOBS<br />

• TIPOS ANY<br />

• TIPOS DEFINIDOS POR EL USUARIO<br />

– TIPOS DISTINTOS<br />

– TIPOS ESTRUCTURADOS<br />

– TIPOS REF<br />

– MÉTODOS<br />

– HERENCIA<br />

– TIPOS COLECCIÓN: NESTED TABLES Y VARRAYS<br />

– EVOLUCIÓN DE TIPOS<br />

6


TIPOS DEFINIDOS POR EL<br />

USUARIO<br />

• Al igual que el estándar SQL:2003, <strong>Oracle</strong><br />

soporta dos clases de tipos definidos por<br />

el usuario:<br />

– los tipos distintos y<br />

– los tipos estructurados<br />

<strong>ÍNDICE</strong><br />

• LOBS<br />

• TIPOS ANY<br />

• TIPOS DEFINIDOS POR EL USUARIO<br />

– TIPOS DISTINTOS<br />

– TIPOS ESTRUCTURADOS<br />

– TIPOS REF<br />

– MÉTODOS<br />

– HERENCIA<br />

– TIPOS COLECCIÓN: NESTED TABLES Y VARRAYS<br />

– EVOLUCIÓN DE TIPOS<br />

7


TIPOS DISTINTOS<br />

• En SQL-92 las columnas de una tabla se definían<br />

mediante tipos de datos primitivos.<br />

• Dos columnas, con distinta semántica y por tanto,<br />

distinto comportami<strong>en</strong>to, podían estar definidas bajo el<br />

mismo tipo de datos comparti<strong>en</strong>do, por tanto, la misma<br />

repres<strong>en</strong>tación.<br />

• Esto daba lugar a incompatibilidades y errores, ya que,<br />

por ejemplo, se podía igualar el atributo LongSala a<br />

AreaSala, si ambos eran de tipo INTEGER. Sin<br />

embargo, esta asignación es semánticam<strong>en</strong>te<br />

incorrecta, ya que estos atributos ti<strong>en</strong><strong>en</strong> un significado y<br />

un comportami<strong>en</strong>to distinto.<br />

TIPOS DISTINTOS<br />

• Con los tipos distintos se resuelve este<br />

problema. Se usan cuando dos tipos de<br />

datos compart<strong>en</strong> una misma<br />

repres<strong>en</strong>tación pero ti<strong>en</strong><strong>en</strong> distinto<br />

comportami<strong>en</strong>to.<br />

• La definición de tipos distintos se basa <strong>en</strong><br />

el r<strong>en</strong>ombrado de tipos, de tal modo que<br />

el tipo distinto no es comparable con el<br />

tipo fu<strong>en</strong>te.<br />

8


SQL:2003<br />

TIPOS DISTINTOS<br />

CREATE TYPE tipoSala<br />

AS CHAR(10) FINAL;<br />

CREATE TYPE tipoMetros<br />

AS INTEGER FINAL;<br />

CREATE TYPE tipoMetrosCuad<br />

AS INTEGER FINAL;<br />

CREATE TABLE Sala (<br />

IdSala tipoSala,<br />

LongSala tipoMetros,<br />

AnchoSala tipoMetros,<br />

AreaSala tipoMetrosCuad,<br />

PerimSala tipoMetros));<br />

<strong>ÍNDICE</strong><br />

Incorrecto<br />

UPDATE Sala<br />

SET AreaSala=LongSala;<br />

Correcto<br />

UPDATE Sala<br />

SET AnchoSala=LongSala;<br />

• LOBS<br />

• TIPOS ANY<br />

• URI TYPES<br />

• TIPOS DEFINIDOS POR EL USUARIO<br />

– TIPOS DISTINTOS<br />

– TIPOS ESTRUCTURADOS<br />

– TIPOS REF<br />

– MÉTODOS<br />

– HERENCIA<br />

– TIPOS COLECCIÓN: NESTED TABLES Y VARRAYS<br />

– EVOLUCIÓN DE TIPOS<br />

9


TIPOS ESTRUCTURADOS<br />

• Se utilizan:<br />

– como tipos de una columna,<br />

– como tipos de un atributo de otro tipo definido por el<br />

usuario o<br />

– como el tipo de una tabla.<br />

• Cuando se utilizan como el tipo de una columna<br />

o de un atributo, son tipos de datos valor;<br />

• Cuando se utilizan como el tipo de una tabla se<br />

conviert<strong>en</strong> <strong>en</strong> tipos de <strong>objeto</strong>s.<br />

TIPOS ESTRUCTURADOS<br />

• Se defin<strong>en</strong> mediante la cláusula<br />

CREATE TYPE AS OBJECT,<br />

• tanto para definir un tipo de dato valor,<br />

como para definir un tipo de <strong>objeto</strong>.<br />

• Lo que determinará si se trata de un tipo<br />

de dato valor o un tipo de <strong>objeto</strong> es el que<br />

dicho tipo se utilice como el tipo de una<br />

columna (o un atributo) o como el tipo de<br />

una fila.<br />

10


TIPOS ESTRUCTURADOS<br />

• Un ejemplo de tipo estructurado, utilizado como<br />

tipo de dato valor <strong>en</strong> <strong>Oracle</strong> (ya que se utiliza <strong>en</strong><br />

la definición de una columna de una tabla<br />

<strong>relacional</strong> ):<br />

CREATE OR REPLACE TYPE tipoDireccion AS OBJECT(<br />

calle VARCHAR2 (30),<br />

ciudad VARCHAR2 (20),<br />

provincia VARCHAR2 (2),<br />

CP VARCHAR2 (5))<br />

/<br />

CREATE TABLE Persona (<br />

nombre VARCHAR2(30),<br />

vive_<strong>en</strong> tipoDireccion,<br />

foto BLOB);<br />

TIPOS ESTRUCTURADOS<br />

• Un tipo de <strong>objeto</strong> se define igual que un tipo<br />

estructurado. La difer<strong>en</strong>cia radica <strong>en</strong> que no se<br />

usa como el tipo de una columna, sino como el<br />

tipo de una tabla tipada.<br />

CREATE OR REPLACE TYPE tipoEmpleado AS OBJECT<br />

( DNI NUMBER,<br />

nombre VARCHAR2(30),<br />

fecha_nac DATE)<br />

/<br />

CREATE TABLE Empleado OF tipoEmpleado;<br />

11


TIPOS ESTRUCTURADOS<br />

• En este caso, el tipo estructurado<br />

tipoEmpleado, es un tipo de <strong>objeto</strong>, ya que<br />

se utiliza como el tipo de la tabla<br />

Empleado.<br />

• Así, la definición del tipo especifica la<br />

int<strong>en</strong>sión (o estructura del mismo)<br />

mi<strong>en</strong>tras que la ext<strong>en</strong>sión se definirá<br />

mediante la creación de una tabla tipada.<br />

TIPOS ESTRUCTURADOS<br />

• Igualm<strong>en</strong>te, pued<strong>en</strong> crearse varias tablas<br />

sobre un mismo tipo estructurado.<br />

– La tabla t<strong>en</strong>drá una columna por cada atributo<br />

del tipo,<br />

– además de la columna REF;<br />

– sus filas van a ser las instancias de los<br />

<strong>objeto</strong>s del tipo de <strong>objeto</strong>.<br />

– Las restricciones (de clave primaria, unicidad,<br />

etc.) se defin<strong>en</strong> sobre la tabla, no sobre el<br />

tipo.<br />

12


<strong>ÍNDICE</strong><br />

• LOBS<br />

• TIPOS ANY<br />

• TIPOS DEFINIDOS POR EL USUARIO<br />

– TIPOS ESTRUCTURADOS<br />

– TIPOS REF<br />

– MÉTODOS<br />

– HERENCIA<br />

– TIPOS COLECCIÓN: NESTED TABLES Y VARRAYS<br />

– EVOLUCIÓN DE TIPOS<br />

TIPOS REF<br />

• Un tipo refer<strong>en</strong>cia (REF) es un tipo de<br />

datos que conti<strong>en</strong>e el valor del atributo<br />

REF (que se correspondería con el OID)<br />

de una fila de una tabla tipada.<br />

• REF, <strong>en</strong> realidad, es un constructor de<br />

tipo, ya que existe un tipo REF por cada<br />

tabla tipada.<br />

13


TIPOS REF<br />

• Así, <strong>en</strong> el ejemplo de la figura, la columna REF<br />

cont<strong>en</strong>drá valores del tipo REF (tipoPropiedad).<br />

• El tipo refer<strong>en</strong>cia permite implem<strong>en</strong>tar relaciones<br />

prescindi<strong>en</strong>do de la utilización de claves aj<strong>en</strong>as. Un<br />

atributo definido como de tipo refer<strong>en</strong>cia cont<strong>en</strong>drá el<br />

valor del atributo REF del <strong>objeto</strong> refer<strong>en</strong>ciado.<br />

PROPIEDADES<br />

REF precio num_habitaciones tamaño ubicación<br />

TIPOS REF<br />

calle ciudad provincia CP<br />

• En la sigui<strong>en</strong>te s<strong>en</strong>t<strong>en</strong>cia SQL se puede ver la<br />

creación de un tipo tipoPropiedad que conti<strong>en</strong>e<br />

un atributo, propietario, de tipo refer<strong>en</strong>cia al tipo<br />

estructurado tipoPersona.<br />

CREATE TYPE tipoPropiedad AS (<br />

propietario REF (tipoPersona),<br />

precio INTEGER,<br />

num_habitaciones INTEGER,<br />

tamaño DECIMAL (8,2),<br />

ubicacion tipoDireccion);<br />

CREATE TABLE Propiedades OF tipoPropiedad;<br />

14


TIPOS REF<br />

• Un tipo estructurado ti<strong>en</strong>e un tipo refer<strong>en</strong>cia<br />

correspondi<strong>en</strong>te.<br />

• Un tipo refer<strong>en</strong>cia puede ser usado <strong>en</strong> cualquier sitio<br />

donde pueda ser usado otro tipo de datos.<br />

• Aunque el tipo REF nos va a permitir implem<strong>en</strong>tar<br />

relaciones <strong>en</strong>tre tipos de <strong>objeto</strong>s, hay que t<strong>en</strong>er <strong>en</strong><br />

cu<strong>en</strong>ta que el tipo refer<strong>en</strong>cia no ti<strong>en</strong>e la misma semántica<br />

que la clave aj<strong>en</strong>a.<br />

• Mi<strong>en</strong>tras que la clave aj<strong>en</strong>a implica una dep<strong>en</strong>d<strong>en</strong>cia de<br />

inclusión, debido a la restricción de integridad refer<strong>en</strong>cial,<br />

el tipo REF no, permitiéndose la posibilidad de<br />

refer<strong>en</strong>cias que no apunt<strong>en</strong> a ninguna parte (son las<br />

d<strong>en</strong>ominadas “dangling refer<strong>en</strong>ces”).<br />

• Además, el tipo REF soporta la noción de tipado fuerte<br />

que no va ligada a una clave aj<strong>en</strong>a; de este modo, un<br />

atributo de tipo REF puede, por ejemplo, usarse como<br />

parámetro <strong>en</strong> la llamada de un método.<br />

TIPOS REF<br />

• Los tipos refer<strong>en</strong>cia permit<strong>en</strong> navegar de una tabla a<br />

otra, eliminando la necesidad de joins del modelo<br />

<strong>relacional</strong>.<br />

CREATE OR REPLACE TYPE tipoDepartam<strong>en</strong>to AS OBJECT<br />

( nombre_Dep VARCHAR2(30))<br />

/<br />

CREATE OR REPLACE TYPE tipoEmpleado AS OBJECT<br />

( DNI NUMBER,<br />

nombre VARCHAR2(30),<br />

fecha_nac DATE,<br />

pert<strong>en</strong>ece_a REF tipoDepartam<strong>en</strong>to)<br />

/<br />

CREATE TABLE Departam<strong>en</strong>to OF tipoDepartam<strong>en</strong>to;<br />

CREATE TABLE Empleado OF tipoEmpleado;<br />

15


TIPOS REF<br />

• De este modo, las relaciones podrán seguir<br />

implem<strong>en</strong>tándose mediante claves aj<strong>en</strong>as, o bi<strong>en</strong><br />

utilizar refer<strong>en</strong>cias.<br />

• Para las consultas que involucr<strong>en</strong> a dos tablas, <strong>en</strong><br />

el primer caso se seguirán realizando mediante<br />

joins, mi<strong>en</strong>tras que <strong>en</strong> el caso de haberlas<br />

relacionado mediante refer<strong>en</strong>cias se realizarán<br />

utilizando la notación “punto”:<br />

SELECT nombre, e.pert<strong>en</strong>ece_a.nombre_Dep<br />

FROM Empleado e<br />

WHERE DNI=9687452;<br />

que devolvería el nombre del empleado con DNI<br />

9687452, así como el nombre del departam<strong>en</strong>to al<br />

que pert<strong>en</strong>ece.<br />

<strong>ÍNDICE</strong><br />

• LOBS<br />

• TIPOS ANY<br />

• TIPOS DEFINIDOS POR EL USUARIO<br />

– TIPOS ESTRUCTURADOS<br />

– TIPOS REF<br />

– MÉTODOS<br />

– HERENCIA<br />

– TIPOS COLECCIÓN: NESTED TABLES Y VARRAYS<br />

– EVOLUCIÓN DE TIPOS<br />

16


MÉTODOS<br />

• Es posible asociar comportami<strong>en</strong>to a los tipos<br />

de <strong>objeto</strong>s, defini<strong>en</strong>do la cabecera de los<br />

métodos como parte de la definición del tipo:<br />

CREATE OR REPLACE TYPE tipoEmpleado AS OBJECT<br />

( DNI NUMBER,<br />

nombre VARCHAR2(30),<br />

fecha_nac DATE,<br />

pert<strong>en</strong>ece_a REF tipoDepartam<strong>en</strong>to,<br />

MEMBER FUNCTION edad RETURN NUMBER)<br />

/<br />

CREATE TABLE Empleado OF tipoEmpleado;<br />

MÉTODOS<br />

• Los métodos de un tipo se declaran como<br />

funciones miembro y no como métodos. El<br />

cuerpo del método se define por separado.<br />

CREATE TYPE BODY tipoEmpleado AS<br />

MEMBER FUNCION edad RETURN NUMBER IS<br />

BEGIN<br />

...<br />

RETURN edad;<br />

END;<br />

END;<br />

/<br />

17


MÉTODOS<br />

• Los métodos recib<strong>en</strong> siempre como parámetro<br />

implícito la lista de atributos del tipo de <strong>objeto</strong> al<br />

que pert<strong>en</strong>ec<strong>en</strong>.<br />

• La palabra reservada a través de la cual un<br />

método se refiere a dichos atributos es SELF.<br />

Así, por ejemplo, SELF.nombre, hace refer<strong>en</strong>cia<br />

al nombre de un empleado concreto.<br />

• Puede existir sobrecarga <strong>en</strong> la definición de<br />

métodos. Es decir, puede haber dos métodos<br />

que se llam<strong>en</strong> igual siempre que sus parámetros<br />

formales varí<strong>en</strong> <strong>en</strong> número, ord<strong>en</strong> o tipo de<br />

dato.<br />

MÉTODOS<br />

• Cada tipo de <strong>objeto</strong> ti<strong>en</strong>e un método<br />

constructor; se trata de una función definida por<br />

el sistema con el mismo nombre que el tipo de<br />

<strong>objeto</strong>.<br />

• El constructor inicializa y devuelve una instancia<br />

del tipo de <strong>objeto</strong>.<br />

• Los parámetros formales que recibe el<br />

constructor son los atributos, <strong>en</strong> el mismo ord<strong>en</strong><br />

que se han definido, del tipo de <strong>objeto</strong>.<br />

18


<strong>ÍNDICE</strong><br />

• LOBS<br />

• TIPOS ANY<br />

• TIPOS DEFINIDOS POR EL USUARIO<br />

– TIPOS ESTRUCTURADOS<br />

– TIPOS REF<br />

– MÉTODOS<br />

– HERENCIA<br />

– TIPOS COLECCIÓN: NESTED TABLES Y VARRAYS<br />

– EVOLUCIÓN DE TIPOS<br />

HERENCIA<br />

• <strong>Oracle</strong> 8 no soportaba una de las características<br />

más importantes de la ori<strong>en</strong>tación al <strong>objeto</strong>, la<br />

her<strong>en</strong>cia. Desde la versión 9i de <strong>Oracle</strong> se<br />

incorpora ya la her<strong>en</strong>cia simple de tipos, pero<br />

no soporta la her<strong>en</strong>cia de tablas.<br />

• El tipo raíz de una jerarquía se crea empleando<br />

la s<strong>en</strong>t<strong>en</strong>cia CREATE TYPE y debe ser<br />

declarado como NOT FINAL. La opción por<br />

defecto es FINAL (indicando así, que pued<strong>en</strong><br />

derivarse subtipos de él).<br />

19


HERENCIA<br />

CREATE TYPE tipoPersona AS<br />

OBJECT<br />

(DNI VARCHAR(9),<br />

nombre VARCHAR(25),<br />

fecha_nac DATE,<br />

direccion VARCHAR(1000),<br />

MEMBER FUNCTION edad<br />

RETURN NUMBER)<br />

NOT INSTANTIABLE NOT FINAL<br />

/<br />

CREATE TYPE tipoEstudiante UNDER<br />

tipoPersona<br />

(estudios VARCHAR(50))<br />

/<br />

CREATE TYPE tipoEmpleado UNDER<br />

tipoPersona<br />

(empresa VARCHAR(50))<br />

/<br />

Estudiante<br />

estudios: String<br />

HERENCIA<br />

Persona<br />

DNI: String<br />

nombre: String<br />

fecha_nac: Date<br />

direccion: String<br />

edad(): Integer<br />

Empleado<br />

empresa: String<br />

• La her<strong>en</strong>cia simple de tipos que contempla<br />

<strong>Oracle</strong> implica que cualquier subtipo hereda de<br />

su padre los métodos y atributos que posea.<br />

• Así, para el ejemplo pres<strong>en</strong>tado, los subtipos<br />

tipoEstudiante y tipoEmpleado pose<strong>en</strong> los dos la<br />

función edad().<br />

• Por tanto, esta función podrá ser invocada sobre<br />

cualquier instancia de estos tipos, es decir,<br />

cuando se defina una tabla de cualquiera de los<br />

dos subtipos, podremos llamar a la función<br />

edad() sobre cualquiera de las filas de la tabla<br />

(que no son sino <strong>objeto</strong>s).<br />

20


HERENCIA<br />

• La característica [NOT] FINAL permite<br />

indicar si la clase puede t<strong>en</strong>er subclases o<br />

no<br />

• La característica [NOT] INSTANTIABLE<br />

permite indicar si la clase va a poder<br />

instanciarse o no.<br />

HERENCIA<br />

• Es muy importante t<strong>en</strong>er <strong>en</strong> cu<strong>en</strong>ta que <strong>Oracle</strong><br />

no soporta la her<strong>en</strong>cia de tablas; es decir, la<br />

definición de jerarquías de tablas sobre tipos<br />

que están integrados <strong>en</strong> una jerarquía de tipos.<br />

• <strong>Oracle</strong> sólo permite asegurar que los atributos y<br />

métodos del supertipo de la tabla padre, se<br />

heredarán <strong>en</strong> las tablas definidas sobre los<br />

subtipos.<br />

• Sin embargo, las restricciones, disparadores,<br />

etc. definidos para una tabla no podrán ser<br />

heredados por otras tablas, aunque sus tipos<br />

subyac<strong>en</strong>tes pert<strong>en</strong>ezcan a la misma jerarquía.<br />

21


HERENCIA<br />

• A continuación se muestran las s<strong>en</strong>t<strong>en</strong>cias para<br />

crear las tablas del tipo padre y de los dos<br />

subtipos.<br />

• Es necesario definir <strong>en</strong> cada tabla sus propias<br />

restricciones, ya que éstas no se propagan:<br />

CREATE TABLE Persona OF tipoPersona<br />

(PRIMARY KEY (DNI),<br />

CHECK(direccion like (‘%Madrid%’)));<br />

CREATE TABLE Estudiante OF tipoEstudiante<br />

(PRIMARY KEY (nombre));<br />

CREATE TABLE Empleado OF tipoEmpleado<br />

(PRIMARY KEY (DNI));<br />

HERENCIA<br />

• Las tablas Estudiante y Empleado definidas sobre<br />

subtipos del tipo tipoPersona no deb<strong>en</strong> cumplir <strong>en</strong><br />

absoluto las restricciones impuestas para la tabla<br />

Persona definida sobre el tipo padre TipoPersona.<br />

• Así, por ejemplo, podemos insertar <strong>en</strong> la tabla Empleado<br />

una fila <strong>en</strong> la que el valor del atributo direccion no<br />

cont<strong>en</strong>ga la cad<strong>en</strong>a ‘Madrid’, mi<strong>en</strong>tras que <strong>en</strong> la tabla<br />

Persona nos sería imposible.<br />

• Así mismo, podemos definir el campo nombre como<br />

clave primaria <strong>en</strong> la tabla Estudiante, aunque <strong>en</strong> la tabla<br />

padre Persona la clave primaria se definió sobre el<br />

campo DNI.<br />

22


HERENCIA<br />

• Pero, además de que las tablas no hered<strong>en</strong> las<br />

restricciones de la tabla definida para el supertipo, existe<br />

un problema aun mayor, y es que con el ejemplo<br />

anterior, no podemos recoger el hecho, implícito <strong>en</strong> toda<br />

jerarquía, de que todo estudiante es persona y de que<br />

todo empleado es persona.<br />

• Esto es debido a que no existe relación alguna <strong>en</strong>tre las<br />

tablas, no hay nada que le indique al SGBD que un<br />

empleado o un alumno es también una persona. Por<br />

ello, al realizar una consulta a persona, obt<strong>en</strong>dríamos<br />

sólo aquellas personas que no fueran ni estudiantes ni<br />

empleados.<br />

HERENCIA<br />

• De este modo, para la implem<strong>en</strong>tación de<br />

una jerarquía <strong>en</strong> <strong>Oracle</strong>, aunque podamos<br />

apoyarnos <strong>en</strong> ocasiones <strong>en</strong> la utilización<br />

de la her<strong>en</strong>cia de tipos, necesitamos<br />

además recurrir a los clásicos<br />

mecanismos empleados <strong>en</strong> <strong>relacional</strong><br />

(claves aj<strong>en</strong>as, o refer<strong>en</strong>cias, <strong>en</strong>tre las<br />

tablas, restricciones, vistas, etc.).<br />

23


<strong>ÍNDICE</strong><br />

• LOBS<br />

• TIPOS ANY<br />

• TIPOS DEFINIDOS POR EL USUARIO<br />

– TIPOS ESTRUCTURADOS<br />

– TIPOS REF<br />

– MÉTODOS<br />

– HERENCIA<br />

– TIPOS COLECCIÓN: NESTED TABLES Y VARRAYS<br />

– EVOLUCIÓN DE TIPOS<br />

TIPOS COLECCIÓN<br />

• <strong>Oracle</strong> soporta dos tipos de colecciones: VARRAY y<br />

NESTED TABLE.<br />

• El tipo VARRAY es un tipo de longitud variable; es decir,<br />

se almac<strong>en</strong>a sólo la longitud ocupada del array.<br />

CREATE OR REPLACE TYPE tipoTelefono<br />

AS VARRAY (3) of VARCHAR(10)<br />

/<br />

CREATE TABLE Empleado<br />

( DNI NUMBER,<br />

nombre VARCHAR2(30),<br />

telefonos_contacto tipoTelefono);<br />

INSERT INTO Empleado<br />

VALUES (‘9876543’, ‘Pepe’, tipoTelefono (‘914445566’, ‘606445566’,<br />

‘934445566’));<br />

24


TIPOS COLECCIÓN<br />

• Desde una s<strong>en</strong>t<strong>en</strong>cia SELECT no es<br />

posible acceder a los elem<strong>en</strong>tos<br />

individuales del VARRAY indexándolos;<br />

• Para el tratami<strong>en</strong>to individual de cada<br />

elem<strong>en</strong>to del VARRAY, es necesario<br />

hacerlo mediante PL/SQL, que<br />

proporciona cláusulas para posicionarse<br />

<strong>en</strong> los distintos elem<strong>en</strong>tos del array.<br />

TIPOS COLECCIÓN<br />

• <strong>Oracle</strong> soporta otro tipo de datos colección que<br />

son las tablas anidadas o NESTED TABLES.<br />

• Es posible definir un tipo de datos como una<br />

tabla, y utilizar dicho tipo como el tipo de datos<br />

de la columna de otra tabla.<br />

• De este modo, la columna cont<strong>en</strong>drá una<br />

colección de valores, <strong>objeto</strong>s o refer<strong>en</strong>cias, que<br />

se almac<strong>en</strong>arán <strong>en</strong> formato de tabla.<br />

• Aunque <strong>Oracle</strong> almac<strong>en</strong>a las filas de una<br />

NESTED TABLE sin ord<strong>en</strong>, al recuperarlas es<br />

posible referirse a ellas según un ord<strong>en</strong> de<br />

indexación que empieza <strong>en</strong> el 1.<br />

25


TIPOS COLECCIÓN<br />

CREATE TYPE tipoNombres AS VARRAY(5) OF vARCHAR(20)<br />

CREATE TYPE tipoPlano AS OBJECT<br />

( plano_ID NUMBER,<br />

num_figuras NUMBER,<br />

arquitectos tipoNombres)<br />

CREATE TABLE Plano OF tipoPlano<br />

(PRIMARY KEY (plano_Id));<br />

CREATE OR REPLACE TYPE refTipoPlano AS OBJECT<br />

(refPlano REF tipoPlano)<br />

CREATE OR REPLACE TYPE NT_Planos AS TABLE OF<br />

refTipoPlano<br />

CREATE OR REPLACE TYPE tipoProyecto AS OBJECT<br />

( proyecto_ID NUMBER,<br />

nombre VARCHAR(30),<br />

ti<strong>en</strong>e_plano NT_Planos)<br />

/<br />

CREATE TABLE Proyecto OF tipoProyecto<br />

(PRIMARY KEY (proyecto_ID),<br />

UNIQUE (nombre))<br />

NESTED TABLE ti<strong>en</strong>e_plano STORE AS ListaPlanos;<br />

INSERT INTO Plano VALUES (1, 5,NULL);<br />

INSERT INTO Plano VALUES (2, 4,NULL);<br />

DECLARE<br />

p1_ref refTipoPlano;<br />

p2_ref refTipoPlano;<br />

--Se utilizan refer<strong>en</strong>cias a los dos nuevos<br />

--planos para introducir valores <strong>en</strong> la tabla<br />

--anidada creada<br />

BEGIN<br />

SELECT refTipoPlano(REF(p1)) INTO p1_ref<br />

FROM Plano p1 WHERE p1.plano_id=1;<br />

SELECT refTipoPlano(REF(p2)) INTO p2_ref<br />

FROM Plano p2 WHERE p2.plano_id=2;<br />

INSERT INTO Proyecto<br />

VALUES (1, 'MIDAS', NT_Planos (p1_ref, p2_ref));<br />

END;<br />

/<br />

TIPOS COLECCIÓN<br />

• Al definir una tabla tipada que conti<strong>en</strong>e un atributo que<br />

es de tipo tabla, es necesario darle un nombre de<br />

almac<strong>en</strong>ami<strong>en</strong>to a la NESTED TABLE mediante la<br />

cláusula STORE AS que es un nombre interno y no se<br />

puede utilizar para acceder directam<strong>en</strong>te a la tabla<br />

anidada.<br />

• La tabla anidada es un tipo colección y funciona como<br />

tal. Por tanto, el acceso a sus miembros (bi<strong>en</strong> para<br />

inserción, borrado o consulta) es necesario hacerlo a<br />

través de la tabla principal.<br />

SELECT P.proyecto_ID, Pl.refplano.Plano_ID,<br />

Pl.refplano.num_figuras<br />

FROM Proyecto P, TABLE(P.ti<strong>en</strong>e_plano) Pl<br />

WHERE P.Nombre='MIDAS';<br />

26


TIPOS COLECCIÓN<br />

• Las principales difer<strong>en</strong>cias <strong>en</strong>tre los tipos<br />

colección VARRAY y NESTED TABLE son:<br />

– Los VARRAYS ti<strong>en</strong><strong>en</strong> un tamaño máximo fijo que se<br />

especifica <strong>en</strong> la definición del tipo, mi<strong>en</strong>tras que las<br />

NESTED TABLES son de tamaño variable (no se<br />

dim<strong>en</strong>sionan).<br />

– A la hora del almac<strong>en</strong>ami<strong>en</strong>to <strong>en</strong> la base de datos,<br />

los VARRAYS se guardan <strong>en</strong> el mismo espacio que<br />

la tabla. Sin embargo, las NESTED TABLES se<br />

almac<strong>en</strong>an como otra tabla indep<strong>en</strong>di<strong>en</strong>te asociada a<br />

la tabla sobre la que está definida, pero sobre la que<br />

solo se pued<strong>en</strong> realizar consultas a través de la tabla<br />

<strong>en</strong> la que esta definida.<br />

TIPOS COLECCIÓN<br />

• Cuando se necesite emplear un tipo colección, a la hora<br />

de elegir <strong>en</strong>tre una NESTED TABLE o un VARRAY hay<br />

varios criterios a seguir<br />

– Si el ord<strong>en</strong> <strong>en</strong> que se almac<strong>en</strong>an los elem<strong>en</strong>tos de la colección<br />

es relevante, se emplea un VARRAY, puesto que la NESTED<br />

TABLE no conservan el ord<strong>en</strong>.<br />

– En caso de saber de antemano el número de elem<strong>en</strong>tos que<br />

t<strong>en</strong>drá la colección, se emplea un VARRAY porque permite<br />

limitar su tamaño <strong>en</strong> el mom<strong>en</strong>to de su definición.<br />

– En g<strong>en</strong>eral, si el tamaño y el ord<strong>en</strong> no son especialm<strong>en</strong>te<br />

relevantes: si se necesitan consultas sobre la colección, que nos<br />

permitan tratar los elem<strong>en</strong>tos de la colección por separado, se<br />

emplea una NESTED TABLE, mi<strong>en</strong>tras que si se desea<br />

recuperar la colección como un todo, se empleará un VARRAY,<br />

aunque también se permitiría el acceso a los elem<strong>en</strong>tos<br />

individuales.<br />

27


<strong>ÍNDICE</strong><br />

• LOBS<br />

• TIPOS ANY<br />

• TIPOS DEFINIDOS POR EL USUARIO<br />

– TIPOS ESTRUCTURADOS<br />

– TIPOS REF<br />

– MÉTODOS<br />

– HERENCIA<br />

– TIPOS COLECCIÓN: NESTED TABLES Y VARRAYS<br />

– EVOLUCIÓN DE TIPOS<br />

EVOLUCIÓN DE TIPOS<br />

• La evolución de tipos es un mecanismo que permite al usuario<br />

cambiar la definición de un tipo y propagar esos cambios a otros<br />

<strong>objeto</strong>s del esquema que us<strong>en</strong> el tipo modificado.<br />

• Estos <strong>objeto</strong>s se d<strong>en</strong>ominan dep<strong>en</strong>di<strong>en</strong>tes del tipo y pued<strong>en</strong> ser,<br />

por ejemplo, una tabla, otro tipo o subtipo, una unidad de<br />

programación o bloque PL/SQL (procedimi<strong>en</strong>to, función, paquete o<br />

disparador), etc.<br />

• La evolución de tipos permite realizar las sigui<strong>en</strong>tes modificaciones<br />

sobre un tipo definido por el usuario:<br />

– Añadir y eliminar atributos.<br />

– Añadir y eliminar métodos.<br />

– Modificar un atributo de tipo numérico, cambiando su longitud, precisión<br />

o escala.<br />

– Modificar un atributo de tipo carácter de tamaño variable, para<br />

increm<strong>en</strong>tar el tamaño que admite.<br />

– Cambiar las propiedades final e instantiable de un tipo.<br />

28


EVOLUCIÓN DE TIPOS<br />

• Pero, ¿qué sucede con un <strong>objeto</strong> dep<strong>en</strong>di<strong>en</strong>te cuando<br />

se modifica el tipo del que dep<strong>en</strong>de? Esto estará <strong>en</strong><br />

función de la naturaleza del <strong>objeto</strong> y de la modificación<br />

efectuada.<br />

• Por ejemplo, si el <strong>objeto</strong> es una tabla, por cada atributo<br />

añadido al tipo se añad<strong>en</strong> a la tabla una o varias<br />

columnas, según el tipo del nuevo atributo añadido al<br />

tipo (esos nuevos atributos se añad<strong>en</strong> con valor nulo).<br />

• En el caso de eliminar atributos <strong>en</strong> el tipo, las columnas<br />

del <strong>objeto</strong> dep<strong>en</strong>di<strong>en</strong>te asociadas con esos atributos son<br />

eliminadas, y si lo que se hace es modificar la definición<br />

del atributo (escala, tamaño...), se realizan las mismas<br />

modificaciones <strong>en</strong> las columnas del <strong>objeto</strong> dep<strong>en</strong>di<strong>en</strong>te<br />

asociadas con dicho atributo.<br />

EVOLUCIÓN DE TIPOS<br />

• Introducir estas modificaciones <strong>en</strong> los <strong>objeto</strong>s<br />

dep<strong>en</strong>di<strong>en</strong>tes requiere:<br />

– por un lado, modificar los metadatos (información<br />

sobre la estructura de una tabla, que describe sus<br />

columnas y los tipos de éstas), lo cual no consume<br />

demasiado tiempo, y,<br />

– por otro, modificar los datos de la tabla para reflejar la<br />

redefinición del tipo; si hay una gran cantidad de<br />

datos, esta modificación puede consumir una<br />

importante cantidad de tiempo, por ello, <strong>Oracle</strong><br />

proporciona opciones para la s<strong>en</strong>t<strong>en</strong>cia ALTER TYPE<br />

(empleada para redefinir un tipo), que pospon<strong>en</strong><br />

estas modificaciones <strong>en</strong> los datos hasta que sean<br />

actualizados.<br />

29


EVOLUCIÓN DE TIPOS<br />

• En cualquier caso, <strong>Oracle</strong> siempre devuelve los datos de<br />

una tabla <strong>en</strong> el formato especificado por la última<br />

versión del tipo.<br />

• Así, si la tabla está aún almac<strong>en</strong>ada <strong>en</strong> el formato de<br />

una versión anterior del tipo, <strong>Oracle</strong> convierte los datos<br />

antes de devolverlos, aunque el formato <strong>en</strong> que están<br />

almac<strong>en</strong>ados no cambia hasta que los datos sean<br />

reescritos.<br />

• En el ejemplo sigui<strong>en</strong>te se cambia el tipo tipoPersona,<br />

añadiéndole un atributo y eliminando otro.<br />

• La palabra clave CASCADE propaga el cambio a los<br />

tipos y tablas dep<strong>en</strong>di<strong>en</strong>tes, mi<strong>en</strong>tras que la cláusula<br />

NOT INCLUDING TABLE DATA pospone la conversión<br />

de los datos de esas tablas dep<strong>en</strong>di<strong>en</strong>tes hasta que se<br />

reescriban.<br />

EVOLUCIÓN DE TIPOS<br />

CREATE TYPE tipoPersona AS OBJECT<br />

( nombre VARCHAR(30),<br />

apellidos VARCHAR(30),<br />

edad NUMBER(3))<br />

/<br />

CREATE TABLE Persona OF tipoPersona;<br />

INSERT INTO Persona<br />

VALUES (tipoPersona (‘Pepe’, ‘Sánchez’, 50));<br />

En la consulta se recupera el valor de los <strong>objeto</strong>s de la tabla Persona:<br />

SELECT VALUE(p) FROM Persona p;<br />

El resultado sería el sigui<strong>en</strong>te:<br />

VALUE(P)(NOMBRE, APELLIDOS, EDAD)<br />

----------------------------------------------<br />

TIPOPERSONA (’Pepe', ’Sánchez', 50)<br />

30


EVOLUCIÓN DE TIPOS<br />

A continuación, modificamos el tipo tipoPersona sustituy<strong>en</strong>do el<br />

atributo edad por f_nacimi<strong>en</strong>to. En este punto, la redefinición del tipo<br />

tipoPersona, ha cambiado también la definición de la tabla Persona,<br />

pero los datos de la tabla no han sido modificados aún, para ajustarse<br />

a la nueva definición.<br />

ALTER TYPE tipoPersona<br />

ADD ATTRIBUTE (f_nacimi<strong>en</strong>to DATE),<br />

DROP ATTRIBUTE edad CASCADE NOT INCLUDING TABLE DATA;<br />

Cuando consultamos ahora el valor de los <strong>objeto</strong>s de la tabla Persona<br />

obt<strong>en</strong>emos lo sigui<strong>en</strong>te:<br />

SELECT value(p) FROM TablaPersona p;<br />

VALUE(P)(NOMBRE, APELLIDOS, F_NACIMIENTO)<br />

----------------------------------------------<br />

TIPOPERSONA(’Pepe', ’Sánchez', NULL)<br />

EVOLUCIÓN DE TIPOS<br />

• Cuando la consulta anterior recupera los datos<br />

de la tabla Persona, <strong>Oracle</strong> los modifica para<br />

que concuerd<strong>en</strong> con la nueva definición del tipo.<br />

• En este caso, como se ha añadido un nuevo<br />

atributo, se limita a inicializarlo con valor nulo,<br />

NULL.<br />

• Para borrar tipos con tablas u otros tipos<br />

dep<strong>en</strong>di<strong>en</strong>tes, es necesario borrar antes todos<br />

los <strong>objeto</strong>s dep<strong>en</strong>di<strong>en</strong>tes o bi<strong>en</strong> incluir la<br />

cláusula FORCE.<br />

• Así, por ejemplo, para borrar el tipo tipoPersona,<br />

t<strong>en</strong>dríamos que especificar:<br />

DROP TYPE tipoPersona FORCE;<br />

31

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!