Introducción:Los objetivos de Desarrollo Sostenible
Sql
1. Examen de SQL - BASES DE DATOS
Febrero de 2006
A continuación se presenta la estructura final de algunas tablas que podrían derivarse del
diseño de una BD de reservas de vuelos. También se muestra un ejemplo del contenido de
estas tablas.
ENTIDAD COLUMNAS TIPO COMENTARIO
Nif Carácter(9) Nif del cliente. Clave primaria.
Apellido1 Carácter (40) Primer apellido del cliente.
CLIENTES Apellido2 Carácter(40) Segundo apellido del cliente.
Nombre Carácter(40) Nombre del cliente.
Poblacion Carácter(20) Población de residencia del cliente
Vuelo Numérico (4) Clave primaria. Identificador del vuelo.
id_compañia Carácter (2) Clave primaria. Identificador de la compañía
VUELOS fecha Fecha Clave primaria. Fecha del vuelo.
Origen Carácter (20) Ciudad de Origen del Vuelo
Destino Carácter (20) Ciudad de Destino del Vuelo
Plazas Numérico (5) Numero de plazas ofertadas del Vuelo
Vuelo Numérico (4) Identificador del vuelo.
id_compañia Carácter (2) Identificador de la compañía
OCUPACION_VUELOS fecha Fecha Fecha del vuelo.
Pasajero Carácter(9) Nif del ocupante del asiento.
Asiento Carácter(3) Identificación del asiento ocupado. Si el billete aun
no se encuentra emitido su valor será nulo
CLIENTES
NIF APELLIDO1 APELLIDO2 NOMBRE POBLACION
07345128H PEREZ PEREZ JUAN MADRID
27365138A GARCIA SANCHEZ PAULA CACERES
10134562B LARRA ALVAREZ JUAN PEDRO MADRID
57176355K VAZQUEZ PEDROSA IRENE LONDRES
08124356C TENA TENA ALBERTO MALAGA
VUELOS
VUELO ID-COMPAÑÍA FECHA ORIGEN DESTINO PLAZAS
1003 IB 20/01/2006 MADRID LONDRES 40
1007 AF 20/01/2006 PARIS MALAGA 12
1003 IB 30/01/2006 MADRID LONDRES 20
1007 AF 30/01/2006 PARIS MALAGA 17
OCUPACION_VUELOS
VUELO ID-COMPAÑÍA FECHA PASAJERO ASIENTO
1003 IB 20/01/2006 07345128H 01V
1003 IB 20/01/2006 10134562B 01P
1003 IB 20/01/2006 08124356C 02V
1003 IB 20/01/2006 57176355K 02P
1007 AF 20/01/2006 27365138A
1003 IB 30/01/2006 07345128H 01V
1003 IB 30/01/2006 10134562B 02V
1003 IB 30/01/2006 57176355K
2. Examen de SQL - BASES DE DATOS
Febrero de 2006
Apellidos _____________________________________________________
Nombre ___________________________ DNI______________________
Titulación__________________________________
1. Realizar las siguientes operaciones:
A. Crear la tabla OCUPACION_VUELOS según las especificaciones aparecidas para
dicha tabla en el enunciado y además las siguientes restricciones:
• Clave Primaria
• Clave alterna
• Claves externas
B. Impedir la existencia de vuelos con la misma ciudad de origen y destino en la
misma fecha que otra existente (No pueden existir dos vuelos con origen MADRID
y destino LONDRES para el mismo día).
C. Realizar una reserva para el vuelo PARIS-MALAGA de HOY para el cliente con
NIF 08124356C
A.
CREATE TABLE ocupacion_vuelos
( Vuelo NUMBER(4),
Id_compañia VARCHAR2(2),
Fecha DATE,
Pasajero VARCHAR2(9),
Asiento VARCHAR2(3)
PRIMARY KEY (vuelo,id_compañia,fecha,pasajero),
UNIQUE(vuelo,id_compañia,fecha,asiento),
FOREIGN KEY (vuelo,id_compañia,fecha)
REFERENCES vuelos(vuelo,id_compañia,fecha),
FOREIGN KEY (pasajero) REFERENCES clientes(nif)
);
B.
ALTER TABLE vuelos ADD (UNIQUE (origen,destino,fecha));
ó
CREATE UNIQUE INDEX ind_vuelos
ON vuelos (origen , destino,fecha);
C.
INSERT INTO ocupacion_vuelos
(vuelo,id_compañia,fecha, pasajero)
SELECT vuelo, id_compañia, SYSDATE, '08124356C'
FROM vuelos
WHERE origen='PARIS' AND destino = 'MALAGA'
3. Examen de SQL - BASES DE DATOS
Febrero de 2006
2. Obtener información de los vuelos en los que no se ha realizado ninguna reserva,
ordenado por compañía, mediante al menos 3 de los siguientes tipos de consulta:
A. Operación de conjuntos
B. Subconsulta anidada
C. Subconsulta correlacionada
D. Join
VUELO COMPAÑIA FECHA
---------------------- --------- ----------
1007 AF 30/01/2006
A.
SELECT vuelo, id_compañia AS compañía , fecha
FROM vuelos
MINUS
SELECT DISTINCT vuelo, id_compañia,fecha
FROM ocupacion_vuelos
B.
SELECT vuelo, id_compañia AS compañía , fecha
FROM vuelos
WHERE (vuelo,id_compañia,fecha) NOT IN
(SELECT DISTINCT vuelo,id_compañia,fecha
FROM ocupación_vuelos);
C.
SELECT vuelo, id_compañia AS compañía , fecha
FROM vuelos V
WHERE 0 = ( SELECT COUNT(*)
FROM ocupacion_vuelos O
WHERE v.vuelo=o.vuelo AND
v.id_compañia=o.id_compañia AND
v.fecha=o.fecha);
ó
SELECT vuelo, id_compañia AS compañía , fecha
FROM vuelos V
WHERE NOT EXISTS( SELECT *
FROM ocupacion_vuelos O
WHERE v.vuelo=o.vuelo AND
v.id_compañia=o.id_compañia AND
v.fecha=o.fecha);
D.
SELECT vuelo, id_compañia AS compañía , fecha
FROM vuelos LEFT JOIN ocupacion_vuelos
USING (vuelo,id_compañia,fecha)
WHERE pasajero is NULL;
4. Examen de SQL - BASES DE DATOS
Febrero de 2006
Apellidos _____________________________________________________
Nombre ___________________________ DNI______________________
Titulación__________________________________
3. Obtener información de los clientes que han realizado todos los vuelos desde/hacia su
población de residencia en el mismo asiento. Salida:
CLIENTE ASIENTO
---------- ----------
07345128H O1V
57176355K 02P
SELECT NIF AS CLIENTE , MAX(ASIENTO) AS ASIENTO
FROM CLIENTES JOIN OCUPACION_VUELOS ON (NIF=PASAJERO)
JOIN VUELOS USING (VUELO,ID_COMPAÑIA)
WHERE (ORIGEN=POBLACION OR DESTINO=POBLACION)
GROUP BY NIF
HAVING COUNT(DISTINCT ASIENTO) = 1;
5. Examen de SQL - BASES DE DATOS
Febrero de 2006
4. Rellenar, solo en los casos que sea necesario, el siguiente código PL/SQL. Además,
añadir las instrucciones necesarias para asegurar la atomicidad de las transacciones.
SET SERVEROUTPUT ON;
DECLARE
PROCEDURE reserva_vuelo(nif VARCHAR2, id_vuelo NUMBER,
compañía VARCHAR2, fecha DATE) IS
-- Definir las variables locales necesarias para el procedimiento
Plazas_ofertadas 1 vuelos.plazas%TYPE;
Plazas_ocupadas 1 vuelos.plazas%TYPE;
1 Vuelo_lleno EXCEPTION;
BEGIN
-- Obtener el numero de plazas del vuelo que se va a reservar
2 SELECT plazas INTO plazas_ofertadas
FROM vuelos
WHERE vuelo=reserva_vuelo.id_vuelo AND
Id_compañía=reserva_vuelo.compañia AND
fecha=reserva_vuelo.fecha;
-- Comprobar si existen plazas vacantes para el vuelo.
-- Si no existen plazas lanzar una excepción
3 SELECT COUNT(*) INTO plazas_ocupadas
FROM ocupación_vuelos
WHERE vuelo=reserva_vuelo.id_vuelo AND
Id_compañía=reserva_vuelo.compañia AND
fecha=reserva_vuelo.fecha;
IF plazas_ocupadas >= plazas_ofertadas THEN
RAISE vuelo_lleno;
END IF;
-- Dar de alta el pasaje
4 INSERT INTO ocupación_vuelos (vuelo,id_compañía,fecha,pasajero)
VALUES ( reserva_vuelo.vuelo,reserva_vuelo.compañia,
reserva_vuelo.fecha,reserva_vuelo.nif);
DBMS_OUTPUT.PUT_LINE ('RESERVA REALIZADA');
COMMIT;
EXCEPTION
WHEN 5 NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE ('NO EXISTE EL VUELO INDICADO');
WHEN 6 DUP_VAL_ON_INDEX THEN
DBMS_OUTPUT.PUT_LINE ('EL CLIENTE YA TIENE RESERVADO EL VUELO');
WHEN 7 VUELO_LLENO THEN
DBMS_OUTPUT.PUT_LINE ('NO EXISTEN PLAZAS LIBRES EN EL VUELO');
-- Para cualquier otro tipo de error
WHEN 8 OTHERS THEN
-- Relanzar la misma excepción que se ha producido
ROLLBACK; (No tiene porque ser necesario)
9 RAISE
END;
BEGIN
DBMS_OUTPUT.ENABLE;
Reserva_vuelo ('07345128H' , 1007, 'AF', '30/01/2006');
EXCEPTION
-- Para cualquier error que se produzca
WHEN 10 OTHERS THEN
DBMS_OUTPUT.PUT_LINE ('ERROR EN RESERVA DE VUELO');
END;