IES RIBERA DE CASTILLA DEPARTAMENTO DE INFORMÁTICA Y COMUNICACIONES 29 de abril de 2024 Nombre Apellidos Calificación: BASES DE DATOS 1º DESARROLLO DE APLICACIONES WEB Examen de prueba 2º evaluación Resuelve los problemas que se plantean en las preguntas de la 1 a la 3 teniendo en cuenta el siguiente diseño: (2,5 puntos) PREGUNTA 1: Realiza las siguientes operaciones en lenguaje DML: a) Inserta un nuevo piloto cuya ciudad tenga el código ‘WAS’ y cuya tarjeta sea de la compañía ‘Galah’. INSERT INTO piloto VALUES (12345, 'Victoria', 'Pera', 'Dur', 'WAS', 'C/ Redil, 12', (SELECT num FROM tarjeta WHERE compannia='GALAH') ); b) Inserta una nueva ciudad para Francia. INSERT INTO ciudad VALUES ('AMI', 'AMIENS', (SELECT codPais FROM pais WHERE nombre='FRANCIA'), 926 ); c) Elimina todos los pilotos de Rusia. DELETE FROM Piloto WHERE Ciudad IN (SELECT codCiudad FROM ciudad JOIN pais ON ciudad.pais = pais.codPais WHERE pais.nombre = ‘Rusia’ ); d) Elimina todas las tarjetas que no estén asignadas a ningún piloto. DELETE FROM tarjeta WHERE num NOT IN ( SELECT DISTICT numTarjeta FROM piloto ) ); e) Incrementa en 1000 unidades el tamaño de las ciudades de Chipre. UPDATE ciudad SET tammanno= tammano + 1000 WHERE pais IN ( SELECT codPais FROM pais WHERE nombre='CHIPRE' ) ); (2,5 puntos) PREGUNTA 2: Codifica un procedimiento en el que se defina un cursor para realizar las siguientes operaciones: • Abrir un cursor con el nombre CursorEs que contenga el ID y el numTarjeta de todos los pilotos españoles. • A partir de los datos del cursor, se debe actualizar el modelo de tarjeta a ‘aprendizaje’. El procedimiento debe incluir el tratamiento de errores de ejecución inesperados. DECLARE Id INTEGER; NumTarjeta INTEGER; CURSOR CursorES IS SELECT id, numTarjeta FROM piloto p JOIN ciudad c ON p.ciudad=c.codCiudad JOIN pais pa ON c.pais = pa.codPais WHERE pa.nombre LIKE 'ESPA%'; BEGIN OPEN CursorEs; LOOP FETCH CursorEs INTO id, numTarjeta; EXIT WHEN CursorEs%NOTFOUND; UPDATE tarjeta SET modelo='Aprendizaje' WHERE num=numTarjeta; END LOOP; EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('ERROR INESPERADO: ' || SQLCODE); END; / (2,5 puntos) PREGUNTA 3: Construye un disparador o disparadores en PL/SQL que permita controlar las siguientes restricciones: a) Los pilotos deben ser mayores de edad. CREATE OR REPLACE TRIGGER tr_chk_edad_piloto BEFORE INSERT OR UPDATE ON piloto FOR EACH ROW BEGIN IF (:NEW.edad < 18) THEN raise_application_error(-20001, ‘La edad del piloto debe ser mayor de 18’); END IF; END; / 2 b) Una vez insertado un piloto, su nombre no puede volver a cambiar. CREATE OR REPLACE TRIGGER tr_chk_edad_piloto BEFORE INSERT OR UPDATE ON piloto FOR EACH ROW BEGIN IF ( :NEW.nombre <> :OLD.nombre OR :NEW.ape1 <> :OLD.ape1 OR :NEW.ape2 <> :OLD.ape2 ) THEN raise_application_error(-20002, 'El nombre del piloto no puede cambiar.'); END IF; END; / (2,5 puntos) PREGUNTA 4: Realiza cada uno de los ejercicios sobre bases de datos objeto-relacionales. Emplearemos un diseño de base de datos derivado del de las preguntas 1, 2 y 3. a) Declara el objeto oDireccion de la siguiente forma: - tipoVia, 10 caracteres - nombre, 50 caracteres - numero, 3 caracteres - portal, 3 caracteres - piso, 3 caracteres - puerta, 3 caracteres CREATE OR REPLACE TYPE oDireccion AS OBJECT ( tipoVia VARCHAR(10), nombre VARCHAR(50), numero VARCHAR(3), portal VARCHAR(3), piso VARCHAR(3), puerta VARCHAR(3) ); / b) Declara el objeto oPiloto de la siguiente forma - id, entero - nombre, 25 caracteres - ape1, 25 caracteres - ape2, 25 caracteres - ciudad referencia a objetos oCiudad (considera que ya están creados) - dirección VARRAY de 2 objetos oDireccion. - edad, entero - numTarjeta referencia a objetos oCiudad (considera que ya están creados) CREATE OR REPLACE TYPE oPiloto AS OBJECT ( id INTEGER, nombre VARCHAR(25), ape1 VARCHAR(25), ape2 VARCHAR(25), ciudad REF oCiudad, direccion lista_Direcciones, edad INTEGER, numTarjeta REF oTarjeta ); / 3 c) Crea un constructor para el objeto oDireccion en el que se verifique si tipoVia es uno de estos posibles valores: - Calle - Avenida - Camino - Carretera - Plaza - Travesia En caso contrario se debe provocar una excepción. ALTER TYPE oDireccion ADD CONSTRUCTOR FUNCTION oDireccion ( tipoVia VARCHAR2, nombre VARCHAR2, numero VARCHAR2, portal VARCHAR2, piso VARCHAR2, puerta VARCHAR2 ) RETURN SELF AS RESULT CASCADE; CREATE OR REPLACE TYPE BODY oDireccion AS CONSTRUCTOR FUNCTION oDireccion(tipoVia VARCHAR2, nombre VARCHAR2, numero VARCHAR2, portal VARCHAR2, piso VARCHAR2, puerta VARCHAR2) RETURN SELF AS RESULT IS BEGIN IF ( tipoVia NOT IN ( 'Calle', 'Avenida', 'Camino', 'Carretera', 'Plaza', 'Travesia' ) ) THEN raise_application_error(-20003, 'El genero introducido no corresponde con un codigo correcto.'); END IF; SELF.tipoVia:= tipoVia; SELF.nombre:= nombre; SELF.numero:= numero; SELF.portal:= portal; SELF.piso:= piso; SELF.puerta:= puerta; RETURN; END; END; / d) Crea un método MAP para oPiloto que utilice el campo ID para ordenar los objetos oPiloto. (Usa un DROP TYPE si lo consideras necesario). ALTER TYPE oPiloto ADD MAP MEMBER FUNCTION ordena_piloto RETURN NUMBER; CREATE OR REPLACE TYPE BODY oPiloto AS MAP MEMBER FUNCTION ordena_piloto RETURN NUMBER IS BEGIN RETURN id; END; 4 END; / e) Crea una tabla llamada pilotoOBJS de tipo oPiloto e inserta un nuevo objeto en ella. CREATE TABLE pilotoOBJS OF oPiloto; DECLARE refTarjeta REF oTarjeta; refCiudad REF oCiudad; piloto oPiloto; BEGIN SELECT REF(t) INTO refTarjeta FROM tarjetaOBJS t WHERE num='54321'; SELECT REF(c) INTO refCiudad FROM ciudadOBJS c WHERE codCiudad='MAD'; piloto:= new oPiloto( 12345, 'Mariano', 'Girona', 'Carro', refCiudad, new lista_direciones( new oDireccion( 'Calle', 'Miguel Delibes', '115', '35', '8o', 'F' ), NULL ), 47, refTarjeta ); INSERT INTO pilotoOBJS VALUES(piloto); END; / 5