605 palabras
3 minutos
Resoluci贸n de problemas de tablas mutantes

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:

  1. Leer bien los requisitos del problema e identificar la informaci贸n de la tabla que debo guardar en variables persistentes.
  2. Crear el paquete declarando los tipos de datos y las variables necesarias para guardar dicha informaci贸n.
  3. Hacer un trigger before por sentencia que rellene dichas variables consultando la tabla mutante.
  4. 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:

Tabla puntuaciones

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);
Resoluci贸n de problemas de tablas mutantes
https://www.robertops.com/posts/2022-12-19_tabla-mutante/
Autor
Roberto Rodr铆guez
Publicado el
2022-12-19