Code icon

MySQL - TRIGGERS EXERCISES

Links


    // TRIGGERS EXERCISES
    
    //--1. No deje que un alumno tenga mas de 5 asignaturas en la tabla de notas (comprobarlo al insertar)
    create or alter trigger trMenosDe5Asignaturas on nota for UPDATE
    as
        declare @idAlumno int -- a quien le estas haciendo esto!!
        set @idAlumno=(select idAlumno from deleted) 
        declare @asignaturas int
    
        set @asignaturas = (select count(*) from Nota  WHERE idAlumno=@idAlumno)
        if (@asignaturas > 5)
        begin
            raiserror ('Tiene mas de cinco asignaturas', 16,1)
            rollback transaction
        end
    GO
    
    //--2. No deje que un alumno tenga menos de 3 asignaturas en la tabla de notas (comprobarlo al borrar)
    CREATE OR ALTER TRIGGER trMenosDe3Asignaturas ON Nota FOR DELETE
    AS
        DECLARE @idAlumno INT
        set @idAlumno = (SELECT idAlumno FROM deleted)
        DECLARE @asignaturas INT
        SET @asignaturas = (SELECT COUNT(*) FROM Nota WHERE idAlumno = @idAlumno)
        if (@asignaturas < 3)
        BEGIN
            raiserror ('Tiene menos de tres asignaturas', 16,1)
            rollback transaction
        end
    GO
    
    
    //--3. No deje cambiar el código de la asignatura en la tabla de notas (comprobarlo en el UPDATE)
    CREATE OR ALTER TRIGGER trNoCambiesCodigoASignatura ON Nota FOR UPDATE
    AS
        DECLARE @idAsViejo INT
        DECLARE @idAsNuevo INT
        SET @idAsViejo = (SELECT idAsignatura FROM deleted)
        SET @idAsNuevo = (SELECT idAsignatura FROM inserted)
        if (@idAsViejo <> @idAsNuevo)
        BEGIN
            raiserror ('No cambies el código de la asignatura', 16,1)
            rollback transaction
        END
    GO
    
    //--4. Programar la base de datos de tal forma nos mantenga la nota media de alumno automáticamente. Es decir, según se modifica, añade o borran notas en la tabla de notas de
    //--alumnos, la nota media del alumno se mantiene actualizada.
    alter table alumno add notaMedia float
    
    GO
    
    CREATE OR ALTER PROCEDURE spNotaMedia @idAlumno INT, @nmedia float OUTPUT
    AS
    SET @nmedia = (select AVG( CAST (Nota as float)) from Nota where idAlumno=@idALumno)
    GO
    
    CREATE OR ALTER TRIGGER trActualizarNotaMediaInsert ON Nota FOR INSERT
    AS
        DECLARE @idAlumnoInsertado INT
        DECLARE @nmedia FLOAT
        SET @idAlumnoInsertado = (Select idAlumno FROM inserted)
        EXECUTE spNotaMedia @idAlumnoInsertado, @nmedia OUTPUT
        UPDATE Alumno SET notaMedia = @nmedia WHERE idAlumno = @idAlumnoInsertado
    GO
    
    
    CREATE OR ALTER TRIGGER trActualizarNotaMediaDelete ON Nota FOR DELETE
    AS	
        DECLARE @idAlumno INT
        DECLARE @nmedia FLOAT
        SET @idAlumno = (Select idAlumno FROM deleted)
        EXECUTE spNotaMedia @idAlumno, @nmedia OUTPUT
        UPDATE Alumno SET notaMedia = @nmedia WHERE idAlumno = @idAlumno
    GO
    
    CREATE OR ALTER TRIGGER trActualizarNotaMediaUpdate ON Nota FOR UPDATE
    AS
        DECLARE @idAlumno INT
        DECLARE @nmedia FLOAT
        SET @idAlumno = (Select idAlumno FROM inserted)
        EXECUTE spNotaMedia @idAlumno, @nmedia OUTPUT
        UPDATE Alumno SET notaMedia = @nmedia WHERE idAlumno = @idAlumno
    
        if (UPDATE (idAlumno) ) -- se cambio el idALumno => afecta a otro alumno
        begin
        set @idAlumno =(select idALumno from deleted) -- a qué alumno se le quito laasignatura
        execute spNotaMedia @idAlumno, @nmedia output
        update Alumno set notaMedia = @nmedia where idAlumno =@idAlumno
        end
    go
    
    
    //--5. Crear un campo “Numero_de_notas_suspendidas” en la tabla grupos, de tal forma que
    //--mantenga el valor actualizado del número de suspensos que hay puestos a los alumnos de ese grupo.
    alter table Grupo add NotasSuspendidas INT
    GO
    
    //--a. Hacer procedimiento que nos ponga el valor actual para todos los grupos.
    
    CREATE OR ALTER PROCEDURE spNumNotasSusp @idGrupo CHAR(6), @numNotasS INT OUTPUT
    AS 
        SET @numNotasS = (SELECT COUNT(N.Nota) FROM Nota N INNER JOIN Alumno A ON N.idAlumno = A.idAlumno WHERE A.idGrupo = @idGrupo AND N.Nota < 5)
    GO
    //--b. Hacer que la BD. Mantenga automáticamente ese valor según se ponen notas.
    CREATE OR ALTER TRIGGER trNumNotasSIntr ON Nota FOR INSERT
    AS
        DECLARE @idAlumno INT
        DECLARE @idGrupo CHAR(6)
        DECLARE @numNotasS INT 
        SET @idAlumno = (SELECT idAlumno FROM INSERTED)
        SET @idGrupo = (SELECT idGrupo FROM Alumno WHERE idAlumno = @idAlumno)
        EXECUTE spNumNotasSusp @idGrupo, @numNotasS OUTPUT
        UPDATE GRUPO set NotasSuspendidas = @numNotasS WHERE idGrupo = @idGrupo
        
    GO
    
    CREATE OR ALTER TRIGGER trNumNotasSIntr ON Nota FOR DELETE
    AS
        DECLARE @idAlumno INT
        DECLARE @idGrupo CHAR(6)
        DECLARE @numNotasS INT 
        SET @idAlumno = (SELECT idAlumno FROM DELETED)
        SET @idGrupo = (SELECT idGrupo FROM Alumno WHERE idAlumno = @idAlumno)
        EXECUTE spNumNotasSusp @idGrupo, @numNotasS OUTPUT
        UPDATE GRUPO set NotasSuspendidas = @numNotasS WHERE idGrupo = @idGrupo
    GO
    
    CREATE OR ALTER TRIGGER trNumNotasSIntr ON Nota FOR UPDATE
    AS
        DECLARE @idAlumno INT
        DECLARE @idGrupo CHAR(6)
        DECLARE @numNotasS INT 
        SET @idAlumno = (SELECT idAlumno FROM INSERTED)
        SET @idGrupo = (SELECT idGrupo FROM Alumno WHERE idAlumno = @idAlumno)
        EXECUTE spNumNotasSusp @idGrupo, @numNotasS OUTPUT
        UPDATE GRUPO set NotasSuspendidas = @numNotasS WHERE idGrupo = @idGrupo
    
    
    GO
    
    // FOR TESTING PURPOSES
    //--INSERT INTO Alumno VALUES( 14, 'Alberto', 'Ruiz', '962NMA', 'Heliodoro R L 3',  '38006', '38006', 7)
    //--GO
    //--SELECT * FROM Alumno WHERE idAlumno = 14
    //--INSERT INTO Nota VALUES(14, 22502, 6)
    //--INSERT INTO Nota VALUES(14, 91306, 4)
    //--DELETE FROM Nota WHERE idAlumno = 14 AND idAsignatura = 91306
    //--SELECT * FROM NOTA WHERE idAlumno = 14
    //--SELECT * FROM GRUPO WHERE idGrupo = '962NMA'
    //--SELECT  COUNT(N.Nota) FROM Nota N INNER JOIN Alumno A ON N.idAlumno = A.idAlumno WHERE A.idGrupo = '962NMA' AND N.Nota < 5