Anda di halaman 1dari 15

Creacin de objetos

Los objetos estn formados por:


Una especificacin o interfaz pblica que consta de la declaracin de los atributos y, opcionalmente,

de la definicin de mtodos.
Un cuerpo (parte privada) dnde se implementan los mtodos definidos en la especificacin. Si un

objeto no tiene mtodos definidos, no es necesario definir su cuerpo.


Especificacin:

CREATE or REPLACE TYPE nombreObjeto AS OBJECT (


atributo TIPO,
...,
MEMBER FUNCTION nombreFuncion RETURN Tipo,
MEMBER FUNCTION nombreFuncion2(nomVar TIPO) RETURN Tipo,
MEMBER PROCEDURE nombreProcedimiento,
PRAGMA RESTRICT_REFERENCES (nombreFuncion,restricciones),
PRAGMA RESTRICT REFERENCES (nombreFuncion2,restricciones),
PRAGMA RESTRICT_REFERENCES (nombreProcedimiento,restricciones)
);
Donde restricciones puede ser cualquiera de las siguientes o una combinacin de ellas:

WNDS: Evita que el mtodo pueda modificar las tablas de la BD.

RNDS: Evita que el mtodo pueda leer las tablas de la base de datos.

WNPS: Evita que el mtodo modifique variables del paquete PL/SQL.

RNPS: Evita que el mtodo pueda leer las variables del paquete PL/SQL.

Cuerpo:

CREATE OR REPLACE TYPE BODY nombreObjeto AS


MEMBER FUNCTION nombreFuncion
RETURN Tipo
IS
BEGIN
...

END nombreFuncion;
MEMBER FUNCTION nombreFuncion2(nomVar TIPO)
RETURN Tipo
IS
BEGIN
...
END nombreFuncion2;
MEMBER PROCEDURE nombreProcedimiento
IS BEGIN
...
END nombreProcedimiento;
END; /

Ejemplo de definicin de objetos sin funciones ni cuerpo:

create or replace type direccion_obj as object(


calle varchar2(20),
cp varchar2(5),
poblacion varchar2(20),
provincia varchar2(20)
);
/
create or replace type persona_obj as object(
idpersona number,
dni varchar2(9),
nombre varchar2(15),

apellidos varchar2(30),
fecha_nac date
);
/
Ejemplo de definicin de objetos con funciones y cuerpo:

CREATE or REPLACE TYPE persona AS OBJECT (


idpersona number,
dni varchar2(9),
nombre varchar2(15),
apellidos varchar2(30),
fecha_nac date,
MEMBER FUNCTION muestraEdad RETURN NUMBER,
PRAGMA RESTRICT_REFERENCES (muestraEdad,WNDS)
);
Cuerpo:

CREATE OR REPLACE TYPE BODY persona AS


MEMBER FUNCTION muestraEdad
RETURN NUMBER
IS
BEGIN
return to_char(sysdate, 'YYYY')-to_char(fecha_nac, 'YYYY');
END muestraEdad;
END;
/

Llamar a la funcin o procedimiento:

Para llamar a una funcin o procedimiento bastar con ejecutar aliasTabla.nombreFuncin(parmetros) o


aliasTabla.nombreProcedimiento(). Para ello, es necesario crear antes la tabla que contendr al objeto tal y
como se puede ver en el siguiente apartado.
select p.nombre, p.muestraEdad() from persona p where dni='123456789A';

Creacin de tablas con identidad de objeto


Para poder trabajar con objetos, es imprescindible crear una tabla con identidad de objeto o una tabla con
columnas objeto (tabla sin identidad de objeto). Sobre un objeto no se pueden realizar acciones de insert,
update, etc.
Las tablas con identidad de objeto se utilizan como si de una tabla normal se tratara dnde cada una de sus
filas es una fila del objeto.
create table clientes of persona_obj(
idpersona primary key
);

Insercin de registros

insert into clientes values(1, '123456789', 'aitor', 'rigada', '01/01/1900');

Creacin de tablas sin identidad de objeto


create table clientes(
cliente persona_obj,
direccion direccion_obj,
fecha_alta date );

Insercin de registros

insert into clientes values(


persona_obj(1, '123456789', 'aitor', 'rigada', '01/01/1900'),
direccion_obj('Mimoses S/N', '08000', 'Sant Boi', 'Barcelona'),
sysdate);

Ejemplo de clave primaria (PRIMARY KEY) con tablas Objeto


create type persona_obj as object(

idpersona number,
nombre varchar2(20)
);
Opcin 1:

create table clientes of persona_obj(


idpersona PRIMARY KEY
);
Opcin 2:

create table clientes2 of persona_obj(


CONSTRAINT pk_clientes2 PRIMARY KEY (idpersona)
);

Ejemplo de clave fornea (Foreign Key) con tablas objeto


create type persona_obj as object(
idpersona number,
nombre varchar2(20)
);
/
create table clientes of persona_obj(
idpersona primary key
);
/
create or replace type producto_obj as object(
idproducto number,
nombre varchar2(20),

ffabric date,
idpersona number
);
/
create table productos of producto_obj(
idproducto primary key,
constraint fk_prod_pers foreign key (idpersona) references clientes(idpersona)
);
/
insert into persona values(1, 'aitor');
insert into productos values(1, 'D700', sysdate, 1);

PRIMARY KEY, FOREIGN KEY y CHECK con tablas sin identidad de


objeto
Siguiendo el ejemplo anterior, modificaremos la creacin de la tabla productos para que sta no sea una tabla
objeto. Una vez creada le aadiremos una clave primaria, una fornea y una restriccin check a modo de
ejemplo.
CREATE TABLE productos2(
producto producto_obj,
caducidad DATE,
CONSTRAINT prod2_pk PRIMARY KEY (producto.idproducto),
CONSTRAINT prod2_fk FOREIGN KEY (producto.idpersona)
REFERENCES clientes(idpersona),
CONSTRAINT prod2_check_date CHECK (producto.nombre IS NOT NULL)
);

Ver tipos creados


select * from user_types

Tipos Coleccin: Creacin de VARRAY


Conjunto de elementos ordenados y del mismo tipo. Debemos definir el nmero de posiciones que tendr as
como su tipo. No debemos sobrepasar el nmero de posiciones asignadas en su declaracin.
CREATE TYPE nombreArray AS
VARRAY(NPosiciones) OF Tipo;
/

Ejemplo:

CREATE TYPE lista_compra AS


VARRAY(20) OF VARCHAR2(10);
/
CREATE OR REPLACE TYPE compra_obj AS OBJECT(
idcompra NUMBER,
fecha DATE,
lista lista_compra
);
/
CREATE TABLE compra OF compra_obj(
idcompra PRIMARY KEY,
fecha default SYSDATE
);

Actualizacin (UPDATE) de VARRAY


Las actualizaciones en los VARRAY deben ser atmicas, es decir, podemos modificar el VARRAY totalmente
pero no parcialmente.

Ejemplo:

update compra set lista=lista_compra('item1', item2') where idcompra=42;

Tipos Coleccin: Creacin de NESTED TABLES (Tablas anidadas)


CREATE OR REPLACE TYPE nombreTablaObjeto as OBJECT(

atributo1 TIPO1,
atributo2 TIPO2(n),
...
);
/
CREATE TYPE nombreColeccionObjeto
AS TABLE OF nombreTablaObjeto;
/
CREATE TABLE nombreTabla(
atributo1 TIPO1
atributo2 TIPO2,
tablaAnidada nombreColeccionObjeto)
NESTED TABLE tablaAnidada STORE AS nombre_tabla;
Ejemplo:

CREATE OR REPLACE TYPE persona_obj AS OBJECT(


nombre VARCHAR2(10),
apellidos VARCHAR2(20),
fnacimiento DATE
);
/
CREATE TYPE personaNT AS TABLE OF persona_obj;
/
CREATE TABLE empleados(
idempleado NUMBER PRIMARY KEY,

fecha_alta DATE DEFAULT SYSDATE,


persona personaNT
) NESTED TABLE persona STORE AS personas_tab;

Insertar y seleccionar datos de una NESTED TABLE:


Siguiendo el ejemplo anterior de creacin, podemos insertar datos y posteriormente seleccionarlos tal y como
se muestra a continuacin.
Insercin:

insert into empleados values(1, sysdate, personaNT(


persona_obj2('Nombre1', 'Apellidos1', '07/05/1984'),
persona_obj2('Nombre2', 'Apellidos2', '18/06/1983'),
persona_obj2('Nombre3', 'Apellidos3', '01/10/1980'))
);

Seleccin:

select * from empleados;


Para trabajar con las tablas anidadas, debemos informar que el atributo persona es, en realidad, una tabla. De
esta forma podremos trabajar con su contenido.
select e.fecha_alta, p.nombre from empleados e, table(e.persona) p;

Ejemplo completo de creacin, insercin y actualizacin selectiva


(parcial) de NESTED TABLE
En este ejemplo veremos como crear una tabla de usuarios con una tabla anidada en su interior para
almacenar los contactos de estos usuarios. Una vez creada la tabla insertaremos algunos datos y veremos
como podemos modificar el contenido de una nested table. Podremos observar como, a diferencia de lo que
ocurre con los VARRAY, las tablas anidadas nos permiten hacer una actualizacin selectiva y no total.
Partimos de la base que existe previamente un objeto llamado persona_obj el cual contiene los atributos
nombre (VARCHAR2), apellidos (VARCHAR2) y fnacimiento (DATE).

Creacin de la tabla anidada:

create or replace type contactosTB as table of persona_obj;

Creacin de la tabla usuarios con su tabla anidada como atributo:

create table usuarios(

id number,
nombre varchar2(10),
contactos contactosTB
) nested table contactos store as contactos_TN;

Insercin de registros:

insert into usuarios values(1, 'Aitor', contactosTB(


persona_obj('Toni', 'Gonzales', '05/8/1968'),
persona_obj('Alex', 'Lugo', '07/05/1984'))
);
insert into usuarios values(2, 'Luisa', contactosTB(
persona_obj('Jonathan', 'Garcia', '07/12/1987'))
);
insert into usuarios values(3, 'Hugo', contactosTB(
persona_obj('Pepe', 'Ramos', '20/03/2005'),
persona_obj('Han', 'Ruiz', '25/12/2004'),
persona_obj('Lourdes', 'Sala', '01/01/1999'),
persona_obj('Antonio', 'Lopez', '27/05/1988'))
);

Mostramos los datos para comprobar que la insercin ha sido correcta:

select us.id, us.nombre, cn.nombre from ustest us, table(us.contactos) cn;

Actualizamos la tabla anidada

Modificaremos el usuario con id=3. Cambiaremos el nombre del contacto que se apellida Ramos a Luisa.
update table(select us.contactos from usuarios us where us.id=3)
set nombre='Luisa' where apellidos='Ramos';

Valores por defecto (DEFAULT) en NESTED TABLE y VARRAY

Se pueden definir valores por defecto en una columna de objeto tal y como hemos visto. Tambin es posible
realizar esta accin sobre una columna de tabla anidada o sobre un array.
Sobre el ejemplo anterior quedara de la siguiente manera.
CREATE TABLE empleados(
idempleado NUMBER PRIMARY KEY,
fecha_alta DATE DEFAULT SYSDATE,
persona personaNT DEFAULT personaNT(
persona_obj('Nombre1', 'Apellidos1', '07/05/1984'))
)NESTED TABLE persona STORE AS personas_tab;
Incluso podramos aadir como valor por defecto, a ms de una persona si las separamos mediante comas:
CREATE TABLE empleados(
...,
persona personaNT DEFAULT personaNT(
persona_obj('Nombre1', 'Apellidos1', '07/05/1984'),
persona_obj('Nombre2', 'Apellidos2', '18/06/1983'))
)NESTED TABLE persona STORE AS personas_tab;

Atributos de NESTED TABLE no nulos


Para declarar como NO NULO un atributo de un objeto contenido en una tabla anidada debemos modificar la
tabla generada dnde se van a guardar los datos. Esto no podemos hacerlo en el momento de la creacin de
la tabla sino que debemos hacerlo una vez se ha creado.
ALTER TABLE tabla_generada ADD CONSTRAINT nombre_constraint CHECK(atributo is not
null);
Ejemplo:

CREATE TABLE empleados(


...,
persona personaNT
)NESTED TABLE persona STORE AS personas_tab;

ALTER TABLE personas_tab ADD CONSTRAINT nn_personas_tab_apellido CHECK(apellido


IS NOT NULL);

Herencia
Para permitir la herencia entre objetos debemos especificar la opcin NOT FINAL en la creacin del objeto
para que otros objetos puedan heredar de l (valor por defecto). Si queremos que de un objeto no se pueda
heredar, debemos especificar FINAL. Lo mismo podemos hacer para los procedimientos o funciones miembro.
CREATE TYPE nombreSuperObj AS OBJECT(
nombreAtr TIPO,
... ,
FINAL MEMBER FUNCTION nombreFuncion1 RETURN NUMBER,
MEMBER FUNCTION nombreFuncion2 RETURN VARCHAR2
) NOT FINAL;
Para especificar que un objeto heredar de un objeto padre, se debe especificar la clausula UNDER. Si
adems queremos sobrescribir un mtodo debemos aadir la clausula OVERRIDING antes de MEMBER
(tanto en la especificacin como en el cuerpo del objeto) tal y como podemos ver a continuacin.
CREATE TYPE nombreSubObj UNDER nombreSuperObj(
nombreAtr TIPO,
... ,
OVERRIDING MEMBER FUNCTION nombreFuncion2 RETURN VARCHAR2
) FINAL;

Ejemplo

CREATE TYPE empleado_obj AS OBJECT(


id_empl NUMBER,
sueldo_base NUMBER,
comision NUMBER,
nombre VARCHAR2(10),

apellidos VARCHAR2(25),
MEMBER FUNCTION calc_sueldo_final RETURN NUMBER
) NOT FINAL;
/
CREATE OR REPLACE TYPE BODY empleado_obj AS
MEMBER FUNCTION calc_sueldo_final
RETURN NUMBER
IS
BEGIN
RETURN sueldo_base+sueldo_base*comision;
END calc_sueldo_final;
END;
/
CREATE TYPE ingeniero_obj UNDER empleado_obj(
num_proyectos NUMBER,
fecha_titulacion DATE
) FINAL;
/
CREATE TYPE arquitecto_obj UNDER empleado_obj(
extras NUMBER,
obras_realizadas NUMBER,
OVERRIDING MEMBER FUNCTION calc_sueldo_final RETURN NUMBER
) FINAL;
/

CREATE OR REPLACE TYPE BODY arquitecto_obj AS


OVERRIDING MEMBER FUNCTION calc_sueldo_final
RETURN NUMBER
IS
BEGIN
RETURN sueldo_base+sueldo_base*comision+extras;
END calc_sueldo_final;
END;
/
CREATE TABLE empleados OF empleado_obj;
CREATE TABLE ingenieros OF ingeniero_obj;
CREATE TABLE arquitectos OF arquitecto_obj;

Ejemplo de insercin de registros en objeto heredado

--INSERT INTO arquitectos VALUES(id_empl, sueldo_base, comision, nombre,


apellidos, extras, obras_realizadas);
INSERT INTO arquitectos VALUES(1, 1500, 0.2, 'Nombre1', 'Apellidos1', 500, 12);
--INSERT INTO ingenieros VALUES(id_empl, sueldo_base, comision, nombre,
apellidos, num_proyectos, fecha_titulacion);
INSERT INTO ingenieros VALUES(2, 1500, 0.2, 'Nombre2', 'Apellidos2', 3,
'07/09/2008');
--INSERT INTO empleados VALUES(id_empl, sueldo_base, comision, nombre,
apellidos);
INSERT INTO empleados VALUES(3, 1500, 0.2, 'Nombre3', 'Apellidos3');

select e.nombre, e.sueldo_base, e.calc_sueldo_final() from empleados e;


select i.nombre, i.sueldo_base, i.calc_sueldo_final() from ingenieros i;

select a.nombre, a.sueldo_base, a.calc_sueldo_final() from arquitectos a;