A continuación se presentan 21 ejercicios progresivos sobre Oracle Database que cubren tipos de objetos, herencia de tipos, referencias entre objetos y colecciones VARRAY.
Ejercicio 1: Definición de tipos base
Creamos los tipos básicos T_DIRECCION, T_TELEFONO y T_PROFESOR:
create or replace type T_DIRECCION as object(
calle varchar2(15),
numero varchar2(20),
ciudad varchar2(10),
codigo_postal varchar2(5)
);
create or replace type T_TELEFONO as varray(5) of varchar2(9);
create or replace type T_PROFESOR as object(
nombre varchar2(20),
direccion T_DIRECCION,
salario number,
telefono T_TELEFONO
) not final;

Ejercicio 2: Herencia y creación de tablas
Creamos los subtipos T_CONTRATADO y T_TITULAR y sus tablas correspondientes:
create or replace type T_CONTRATADO under T_PROFESOR();
create or replace type T_TITULAR under T_PROFESOR();
create table PROFESOR of T_PROFESOR(
primary key(nombre)
);
create table PROFESOR_CONTRATADO of T_CONTRATADO(
primary key(nombre),
check(salario <= 166386)
);
create table PROFESOR_TITULAR of T_TITULAR(
primary key(nombre),
check(salario > 166386),
check(direccion is not null)
);

Ejercicio 3: Inserción de datos
Insertamos datos en las tablas de profesores:
insert into PROFESOR_TITULAR values('Jose Mª', T_DIRECCION('Alcalá', '3', 'Madrid', '28020'), 200000, T_TELEFONO('6647401', '4556478', '606754321', null, '914445556'));
insert into PROFESOR_TITULAR values('Jorge', T_DIRECCION('Butarque', '15', 'Leganés', '28911'), 250000, T_TELEFONO('6647401', '4557486', null, '964321236', null));
insert into PROFESOR_TITULAR values('Belen', T_DIRECCION(null, null, null, null), 200000, T_TELEFONO('6647402', null, '606896310',null, null));
insert into PROFESOR_TITULAR values('Esperanza', T_DIRECCION('Serrano', '56', 'Madrid', '28010'), 250000, T_TELEFONO('6647403', '4557486', '606312890', '987348675', null));
insert into PROFESOR_TITULAR(nombre, direccion, salario) values('Paloma', T_DIRECCION('Tulipan', '10', 'Mostoles', '28933'), 300000);
insert into PROFESOR_CONTRATADO values('Pepe', T_DIRECCION('Gran via', '8', 'Madrid', '28009'), 150000, T_TELEFONO('6647405', '4676478', '606757651', '964398736', '914481096'));
insert into PROFESOR_CONTRATADO values('Susana', T_DIRECCION(null, null, 'Leganes', null), 150000, T_TELEFONO('6647405', '4554586', null, '934876823', null));
insert into PROFESOR_CONTRATADO values('Ana', T_DIRECCION(null, null, 'Getafe', null), 100000, T_TELEFONO('6647405', '4490634', '606856670', null, null));
insert into PROFESOR_CONTRATADO values('Juan', T_DIRECCION('Velazquez', '88', 'Madrid', '28010'), 110000, T_TELEFONO('6647406', null, null, '987348675', null));
insert into PROFESOR_CONTRATADO(nombre, salario, telefono) values('Maria', 145000, T_TELEFONO(null, null, null, null, null));
Ejercicio 4: Consulta de todas las tablas
select * from PROFESOR_CONTRATADO;
select * from PROFESOR_TITULAR;
Ejercicio 5: Consultas específicas
select pc.nombre, pc.direccion.ciudad from PROFESOR_CONTRATADO pc where salario > 100000;
select pc.nombre, pc.telefono from PROFESOR_TITULAR pc;
select pc.nombre, pc.direccion from PROFESOR_TITULAR pc where salario > 200000;
select pc.nombre, pc.salario from PROFESOR_TITULAR pc where pc.direccion.ciudad = 'Madrid'
union
select pc.nombre, pc.salario from PROFESOR_CONTRATADO pc where pc.direccion.ciudad = 'Madrid';

Ejercicio 6: Borrar objetos
drop table PROFESOR_TITULAR;
drop table PROFESOR_CONTRATADO;
drop table PROFESOR;
drop type T_TITULAR;
drop type T_CONTRATADO;
drop type T_PROFESOR;
drop type T_TELEFONO;
drop type T_DIRECCION;
Ejercicio 7: Añadir fecha de nacimiento y método edad()
Redefinimos T_PROFESOR añadiendo el atributo fecha_nacimiento y el método edad():
create or replace type T_DIRECCION as object(
calle varchar2(15),
numero varchar2(20),
ciudad varchar2(10),
codigo_postal varchar2(5)
);
create or replace type T_TELEFONO as varray(5) of varchar2(9);
create or replace type T_PROFESOR as object(
nombre varchar2(20),
fecha_nacimiento date,
direccion T_DIRECCION,
salario number,
telefono T_TELEFONO,
member function edad return number
) not final;
create or replace type body T_PROFESOR as
member function edad return number is
ed number;
begin
ed:= to_char(SYSDATE, 'YYYY') - to_char(fecha_nacimiento, 'YYYY');
return ed;
end;
end;
Ejercicio 8: Recrear tablas con fecha de nacimiento
create or replace type T_CONTRATADO under T_PROFESOR();
create or replace type T_TITULAR under T_PROFESOR();
create table PROFESOR of T_PROFESOR(
primary key(nombre)
);
create table PROFESOR_CONTRATADO of T_CONTRATADO(
primary key(nombre),
check(salario <= 166386)
);
create table PROFESOR_TITULAR of T_TITULAR(
primary key(nombre),
check(salario > 166386),
check(direccion is not null)
);
insert into PROFESOR_TITULAR (NOMBRE, FECHA_NACIMIENTO, DIRECCION, SALARIO, TELEFONO)
values('José Mª', '03/11/1966', T_DIRECCION('Alcalá', '3', 'Madrid', '28020'), 200000, T_TELEFONO('6647401', '4556478','606754321', NULL, '914445556'));
insert into PROFESOR_TITULAR (NOMBRE, FECHA_NACIMIENTO, DIRECCION, SALARIO, TELEFONO)
values('Jorge', '12/03/1962', T_DIRECCION('Butarque', '15', 'Leganés', '28911'), 250000, T_TELEFONO('6647401', '4557486',NULL,'964321236', NULL));
insert into PROFESOR_TITULAR (NOMBRE, FECHA_NACIMIENTO, DIRECCION, SALARIO, TELEFONO)
values('Belén','07/10/1964', T_DIRECCION(NULL, NULL, NULL, NULL), 200000, T_TELEFONO('6647402', NULL,'606896310',NULL, NULL));
insert into PROFESOR_TITULAR (NOMBRE, FECHA_NACIMIENTO, DIRECCION, SALARIO, TELEFONO)
values('Esperanza','24/01/1972', T_DIRECCION('Serrano', '56', 'Madrid', '28010'), 250000, T_TELEFONO('6647403', '4457834','606312890','987348675', NULL));
insert into PROFESOR_TITULAR (NOMBRE, FECHA_NACIMIENTO, DIRECCION, SALARIO)
values('Paloma', '02/07/1970', T_DIRECCION('Tulipán', '10', 'Móstoles', '28933'), 300000);
insert into PROFESOR_CONTRATADO (NOMBRE, FECHA_NACIMIENTO, DIRECCION, SALARIO, TELEFONO)
values('Pepe', '03/12/1960', T_DIRECCION('Gran Vía', '8', 'Madrid', '28009'), 150000, T_TELEFONO('6647405', '4676478','606757651', '964398736', '914481096'));
insert into PROFESOR_CONTRATADO (NOMBRE, FECHA_NACIMIENTO, DIRECCION, SALARIO, TELEFONO)
values('Susana', '12/11/1964', T_DIRECCION(Null, Null, 'Leganés', Null), 150000, T_TELEFONO('6647405', '4554586',Null, '934876823', Null));
insert into PROFESOR_CONTRATADO (NOMBRE, FECHA_NACIMIENTO, DIRECCION, SALARIO, TELEFONO)
values('Ana', '04/02/1955', T_DIRECCION(Null, Null, 'Getafe', Null), 100000, T_TELEFONO('6647405', '4490634', '606856670', Null, '914445576'));
insert into PROFESOR_CONTRATADO (NOMBRE, FECHA_NACIMIENTO, DIRECCION, SALARIO, TELEFONO)
values('Juan', '24/10/1963', T_DIRECCION('Velázquez', '88', 'Madrid', '28010'), 110000, T_TELEFONO('6647406', Null, Null, '987348675', Null));
insert into PROFESOR_CONTRATADO (NOMBRE, FECHA_NACIMIENTO, SALARIO, TELEFONO)
values('María', '30/06/1965', 145000, T_TELEFONO(Null, Null, Null, Null, Null));

Ejercicio 9: Nombre y edad de los profesores de Madrid
select pt.nombre, pt.edad()
from PROFESOR_TITULAR pt
where pt.direccion.ciudad = 'Madrid'
union
select pc.nombre, pc.edad()
from PROFESOR_CONTRATADO pc
where pc.direccion.ciudad = 'Madrid';
Ejercicio 10: Borrar todos los objetos
drop table PROFESOR_TITULAR;
drop table PROFESOR_CONTRATADO;
drop table PROFESOR;
drop type T_TITULAR;
drop type T_CONTRATADO;
drop type T_PROFESOR;
drop type T_TELEFONO;
drop type T_DIRECCION;
Ejercicio 11: Definir tipo T_PROFESOR con tabla
create or replace type T_DIRECCION as object(
calle varchar2(15),
numero varchar2(20),
ciudad varchar2(10),
codigo_postal varchar2(5)
);
create or replace type T_TELEFONO as varray(5) of VARCHAR2(9);
create or replace type T_PROFESOR as object(
nombre varchar2(20),
direccion T_DIRECCION,
salario number,
telefono T_TELEFONO
) not final;
create table PROFESOR of T_PROFESOR(
primary key (nombre)
);
Ejercicio 12: Crear T_TITULAR y su tabla
create or replace type T_TITULAR under T_PROFESOR();
create table PROFESOR_TITULAR of T_TITULAR(
primary key (nombre),
check (salario > 166386),
check (direccion is not null)
);
Ejercicio 13: Definir T_ASIGNATURA con referencia REF
create or replace type T_ASIGNATURA as object(
nombre varchar2(20),
curso varchar2(1),
titulacion varchar2(16),
num_creditos number,
prof ref T_PROFESOR
);
create table ASIGNATURA of T_ASIGNATURA;

Ejercicio 14: Insertar profesores y asignaturas
insert into PROFESOR_TITULAR values('Jose Mª', T_DIRECCION('Alcalá', '3', 'Madrid', '28020'), 200000, T_TELEFONO('6647401', '4556478', '6067', null, '914445556'));
insert into PROFESOR_TITULAR values('Jorge', T_DIRECCION('Butarque', '3', 'Leganés', '28911'), 250000, T_TELEFONO('6647401', '4557486', null, '964321236', null));
insert into PROFESOR_TITULAR values('Belén', T_DIRECCION(null, null, null, null), 200000, T_TELEFONO('6647402', '4457834', '6063', '987348675', null));
insert into PROFESOR_TITULAR values('Esperanza', T_DIRECCION('Serrano', '56', 'Madrid', '28010'), 250000, T_TELEFONO('6647403', '4457834', '6063', '987348675', null));
insert into PROFESOR_TITULAR(nombre, direccion, salario) values('Paloma', T_DIRECCION('Tulipán', '10', 'Móstoles', '28933'), 300000);
insert into ASIGNATURA values('Diseño de BD', '3', 'I.T.Informática', 9, (select ref(p) from PROFESOR_TITULAR p where p.nombre = 'Esperanza'));
insert into ASIGNATURA values('Bases de datos', '1', 'I.Informática', 6, (select ref(p) from PROFESOR_TITULAR p where p.nombre like 'Esperanza'));
insert into ASIGNATURA values('Aplicaciones de BD', '2', 'I.Informática', 6, (select ref(p) from PROFESOR_TITULAR p where p.nombre like 'Jose Mª'));
insert into ASIGNATURA values('BD Avanzadas', '3', 'I.T.Informática', 6, (select ref(p) from PROFESOR_TITULAR p where p.nombre like 'Belén'));
insert into ASIGNATURA values('Arquitectura Softw', '2', 'I.Informática', 6, (select ref(p) from PROFESOR_TITULAR p where p.nombre like 'Jorge'));
Ejercicio 15: Consultar el contenido de las tablas
select * from PROFESOR_TITULAR;
select * from ASIGNATURA;

Ejercicio 16: Insertar asignatura duplicada
insert into ASIGNATURA values('Diseño de BD', '3', 'I.T.Informática', 9, (select ref(p) from PROFESOR_TITULAR p where p.nombre = 'Esperanza'));
Ejercicio 17: Borrar profesores de Leganés
delete PROFESOR_TITULAR p where p.direccion.ciudad = 'Leganés';
Ejercicio 18: Verificar tablas tras el borrado
Al borrar un profesor que es referenciado por una asignatura, la referencia queda como dangling reference (referencia colgante).
select * from PROFESOR_TITULAR;
select * from ASIGNATURA;

Ejercicio 19: Consultas a través de referencias
select asig.prof.nombre, asig.prof.telefono
from asignatura asig
where asig.nombre = 'Bases de datos';
select distinct asig.prof.nombre
from asignatura asig
where asig.titulacion = 'I.T.Informática';
Ejercicio 20: Múltiples profesores por asignatura con VARRAY
Modificamos el esquema para que una asignatura pueda impartirla hasta 3 profesores:
drop table ASIGNATURA;
drop type T_ASIGNATURA;
create or replace type T_CONJUNTO_PROFESORES as varray(3) of ref T_TITULAR;
create or replace type T_ASIGNATURA as object(
nombre varchar2(20),
curso varchar2(1),
titulacion varchar2(16),
num_creditos number,
prof T_CONJUNTO_PROFESORES
);
create table ASIGNATURA of T_ASIGNATURA;
Ejercicio 21: Insertar asignaturas con varios profesores
insert into ASIGNATURA values('Diseño de BD', '3', 'I.T.Informática', 9, T_CONJUNTO_PROFESORES(
(select ref(p) from PROFESOR_TITULAR p where p.nombre = 'Esperanza'),
(select ref(p) from PROFESOR_TITULAR p where p.nombre = 'Jose Mª'),
(select ref(p) from PROFESOR_TITULAR p where p.nombre = 'Belén')
));
insert into ASIGNATURA values('Bases de datos', '1', 'I.Informática', 6, T_CONJUNTO_PROFESORES(
(select ref(p) from PROFESOR_TITULAR p where p.nombre like 'Esperanza'),
(select ref(p) from PROFESOR_TITULAR p where p.nombre like 'Belén'),
null
));
insert into ASIGNATURA values('Aplicaciones de BD', '2', 'I.Informática', 6, T_CONJUNTO_PROFESORES(
(select ref(p) from PROFESOR_TITULAR p where p.nombre like 'Jose Mª'),
(select ref(p) from PROFESOR_TITULAR p where p.nombre like 'Esperanza'),
null
));
insert into ASIGNATURA values('BD Avanzadas', '3', 'I.T.Informática', 6, T_CONJUNTO_PROFESORES(
(select ref(p) from PROFESOR_TITULAR p where p.nombre like 'Belén'),
(select ref(p) from PROFESOR_TITULAR p where p.nombre like 'Jose Mª'),
null
));
insert into ASIGNATURA values('Arquitectura Softw', '2', 'I.Informática', 6, T_CONJUNTO_PROFESORES(
(select ref(p) from PROFESOR_TITULAR p where p.nombre like 'Jorge'),
(select ref(p) from PROFESOR_TITULAR p where p.nombre like 'Paloma'),
null
));
