El enunciado a resolver y que contiene una tabla mutante es el siguiente:
6 - Realiza los m贸dulos de programaci贸n necesarios para evitar que un catador puntue m谩s de tres aspectos de una misma versi贸n de un experimento.
En este caso, el trigger principal ser铆a sobre la tabla puntuaciones, y dentro, para comprobar que se cumple la condici贸n de que un catador no punt煤a m谩s de 3 aspectos, se tendr铆a que hacer una consulta a la misma tabla puntuaciones, que en ese caso estar铆a mutando. Para resolver el problema vamos a realizar los siguientes pasos:
- Leer bien los requisitos del problema e identificar la informaci贸n de la tabla que debo guardar en variables persistentes.
- Crear el paquete declarando los tipos de datos y las variables necesarias para guardar dicha informaci贸n.
- Hacer un trigger before por sentencia que rellene dichas variables consultando la tabla mutante.
- Hacer un trigger before por fila que compruebe si el registro que se est谩 manejando cumple la condici贸n especificada consultando las variables persistentes.
Leer bien los requisitos del problema e identificar la informaci贸n de la tabla que debo guardar en variables persistentes
El contenido de la tabla de puntuaciones es el siguiente:
En este caso, tendr铆amos que almacenar en variables persistentes los datos de la consulta, que en este caso son los siguientes campos:
- NIFCatador
- CodigoAspecto
- CodigoExperimento
- CodigoVersion
Crear el paquete declarando los tipos de datos y las variables necesarias para guardar dicha informaci贸n
CREATE OR REPLACE PACKAGE ControlPuntuaciones
AS
TYPE tRegistroTablaPuntuaciones IS RECORD --defino el tipo de datos registro
(
NIFCatador Puntuaciones.NIFCatador%TYPE,
CodigoAspecto Puntuaciones.CodigoAspecto%TYPE,
CodigoExperimento Puntuaciones.CodigoExperimento%TYPE,
CodigoVersion Puntuaciones.CodigoVersion%TYPE
);
TYPE tTablasPuntuaciones IS TABLE OF tRegistroTablaPuntuaciones -- defino el tipo de datos tabla
INDEX BY BINARY_INTEGER;
PuntuacionesCatador tTablasPuntuaciones;
-- declaro una variable del tipo tabla antes creado
END ControlPuntuaciones;
/
Hacer un trigger before por sentencia que rellene dichas variables consultando la tabla mutante
CREATE OR REPLACE TRIGGER RELLENARPUNTUACIONES
BEFORE INSERT OR UPDATE ON Puntuaciones
FOR EACH ROW
DECLARE
CURSOR c_puntuaciones IS SELECT NIFCatador,CodigoAspecto,CodigoExperimento,CodigoVersion
FROM Puntuaciones;
INDICE NUMBER:=0;
indice_u number;
BEGIN
-- vacio el contenido de la tabla
ControlPuntuaciones.PuntuacionesCatador.DELETE;
-- relleno la tabla de puntuaciones los datos que me interesan
FOR v_puntuacion IN c_puntuaciones LOOP
ControlPuntuaciones.PuntuacionesCatador(INDICE).NIFCatador := v_puntuacion.NIFCatador;
ControlPuntuaciones.PuntuacionesCatador(INDICE).CodigoAspecto := v_puntuacion.CodigoAspecto;
ControlPuntuaciones.PuntuacionesCatador(INDICE).CodigoExperimento := v_puntuacion.CodigoExperimento;
ControlPuntuaciones.PuntuacionesCatador(INDICE).CodigoVersion := v_puntuacion.CodigoVersion;
INDICE := INDICE + 1;
END LOOP;
if inserting then
indice_u := ControlPuntuaciones.PuntuacionesCatador.LAST + 1;
ControlPuntuaciones.PuntuacionesCatador(indice_u).NIFCatador := :NEW.NIFCatador;
ControlPuntuaciones.PuntuacionesCatador(indice_u).CodigoAspecto := :NEW.CodigoAspecto;
ControlPuntuaciones.PuntuacionesCatador(indice_u).CodigoExperimento := :NEW.CodigoExperimento;
ControlPuntuaciones.PuntuacionesCatador(indice_u).CodigoVersion := :NEW.CodigoVersion;
end if;
END RELLENARPUNTUACIONES;
/
Hacer un trigger before por fila que compruebe si el registro que se est谩 manejando cumple la condici贸n especificada consultando las variables persistentes
CREATE OR REPLACE TRIGGER ControlarPuntuaciones
BEFORE INSERT OR UPDATE ON Puntuaciones
FOR EACH ROW
DECLARE
BEGIN
-- compruebo que el catador no haya puntuado m谩s de 3 aspectos
IF (NumeroPuntuacionesCatador(:NEW.NIFCatador,:NEW.CodigoExperimento,:NEW.CodigoVersion) > 3) THEN
RAISE_APPLICATION_ERROR(-20001,'El catador no puede puntuar mas de 3 aspectos');
end if;
END;
/
Voy a crear una funcion para comprobar el numero de puntuaciones que tiene un catador en una versi贸n de un experimento:
CREATE OR REPLACE FUNCTION NumeroPuntuacionesCatador
( p_NIFCatador Puntuaciones.NIFCatador%TYPE, p_CodigoExperimento Puntuaciones.CodigoExperimento%TYPE, p_CodigoVersion Puntuaciones.CodigoVersion%TYPE)
RETURN NUMBER
IS
v_NumeroPuntuaciones NUMBER:= 1;
v_cantidad NUMBER;
BEGIN
for i in ControlPuntuaciones.PuntuacionesCatador.FIRST..ControlPuntuaciones.PuntuacionesCatador.LAST
LOOP
if (ControlPuntuaciones.PuntuacionesCatador(i).NIFCatador = p_NIFCatador) and (ControlPuntuaciones.PuntuacionesCatador(i).CodigoExperimento = p_CodigoExperimento) and (ControlPuntuaciones.PuntuacionesCatador(i).CodigoVersion = p_CodigoVersion) then
v_NumeroPuntuaciones := v_NumeroPuntuaciones + 1;
end if;
END LOOP;
return v_NumeroPuntuaciones;
end;
/
--- prueba
create or replace procedure prueba
is
numero number;
begin
numero:=NumeroPuntuacionesCatador('14425879A','A0003-A','0.0.2');
dbms_output.put_line(numero);
end;
/
insert into puntuaciones values('14425879A','0004','A0003-A','0.0.2',7.5);
create or replace procedure imprimirtabla
is
begin
for i in ControlPuntuaciones.PuntuacionesCatador.FIRST..ControlPuntuaciones.PuntuacionesCatador.LAST
LOOP
dbms_output.put_line('Registro numero '|| i);
dbms_output.put_line('NIFCatador: '|| ControlPuntuaciones.PuntuacionesCatador(i).NIFCatador);
dbms_output.put_line('CodigoAspecto: '|| ControlPuntuaciones.PuntuacionesCatador(i).CodigoAspecto);
dbms_output.put_line('CodigoExperimento: '|| ControlPuntuaciones.PuntuacionesCatador(i).CodigoExperimento);
dbms_output.put_line('CodigoVersion: '|| ControlPuntuaciones.PuntuacionesCatador(i).CodigoVersion);
end loop;
end;
/
insert into puntuaciones values('14425879A','0004','A0003-A','0.0.2',7.5);
insert into puntuaciones values('14425879A','0005','A0003-A','0.0.2',7.5);
insert into puntuaciones values('14425879A','0006','A0003-A','0.0.2',7.5);
insert into puntuaciones values('14425879A','0007','A0003-A','0.0.2',7.5);
select * from puntuaciones where nifcatador='14425879A' and codigoexperimento='A0003-A' and codigoversion='0.0.2';
insert into puntuaciones values('14425879A','0005','A0003-A','0.0.1',7.5);