You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
177 lines
6.6 KiB
Markdown
177 lines
6.6 KiB
Markdown
1 year ago
|
---
|
||
|
title: "Resolución de problemas de
|
||
|
tablas mutantes"
|
||
|
date: 2022-12-19T00:51:41+01:00
|
||
|
draft: false
|
||
|
image: featured.png
|
||
|
categories:
|
||
|
- documentación
|
||
|
- Administración de Bases de Datos
|
||
|
tags:
|
||
|
- tablas mutantes
|
||
|
- Oracle
|
||
|
- PL/SQL
|
||
|
---
|
||
|
|
||
|
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](https://i.imgur.com/wMxNzMj.png)
|
||
|
|
||
|
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
|
||
|
|
||
|
```sql
|
||
|
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
|
||
|
|
||
|
```sql
|
||
|
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
|
||
|
|
||
|
```sql
|
||
|
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:
|
||
|
|
||
|
```sql
|
||
|
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;
|
||
|
/
|
||
|
```
|
||
|
|
||
|
|
||
|
|
||
|
```sql
|
||
|
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);
|
||
|
```
|