Ejercicios Resueltos de SQL Server: Triggers, Procedimientos Almacenados y Cursores

Inglés8,93 KB

Ejercicios de Transact-SQL (T-SQL) en SQL Server

A continuación se presenta una serie de ejercicios prácticos orientados a la gestión de una base de datos de autoescuela mediante triggers (disparadores), procedimientos almacenados (stored procedures) y cursores.

Ejercicio 1: Trigger para Actualización de Kilometraje en Prácticas

Enunciado: Crear un trigger tal que, cada vez que se inserta una práctica a un alumno, se sumen 50 km al vehículo que tiene asignado dicho alumno.

CREATE TRIGGER PRAC
ON PRACTICA
FOR INSERT
AS
    DECLARE @CODMON INT
    DECLARE @CODAL INT

    SELECT @CODAL = A.CodMon#
    FROM ALUMNO A 
    INNER JOIN INSERTED I ON A.CodAl# = I.CodAl#

    SELECT @CODMON = M.CodMon#
    FROM MONITOR M 
    INNER JOIN ALUMNO A ON M.CodMon# = A.CodAl#
    WHERE M.CodMon# = @CODMON

    UPDATE COCHE
    SET KMS -= 50
    WHERE CodCoche# = (
        SELECT CodCoche#
        FROM MONITOR
        WHERE CodMon# = @CODAL
    );

Ejercicio 2: Procedimiento Almacenado para Contabilizar Prácticas por Mes y Matrícula

Enunciado: Crear un procedimiento almacenado que, introduciendo la matrícula de un coche y una fecha/mes, devuelva el número de prácticas que ha realizado ese coche en dicho periodo. Se debe validar que los parámetros de entrada no estén vacíos, que el vehículo exista y que el mes esté comprendido entre 1 y 12. Las condiciones de error se deben notificar por pantalla.

CREATE PROCEDURE proc_2
    @PE_MATRICULA CHAR(7),
    @PE_FECHA DATE
AS
    DECLARE @CODMON INT
    DECLARE @CODMON_AL INT
    DECLARE @TOTAL INT

    IF (@PE_MATRICULA = '' OR @PE_FECHA = '')
    BEGIN
        PRINT 'CAMPOS INCORRECTOS';
    END
    ELSE
    BEGIN
        IF (@PE_MATRICULA NOT IN (SELECT DISTINCT MATRICULA FROM COCHE))
        BEGIN
            PRINT 'NO ESTA EN LA BASE DE DATOS';
        END
        ELSE
        BEGIN
            IF (MONTH(@PE_FECHA) < 1 OR MONTH(@PE_FECHA) > 12)
            BEGIN
                PRINT 'FECHA INCORRECTA';
            END
            ELSE
            BEGIN
                SELECT @CODMON = C.CodCOCHE#
                FROM COCHE C
                WHERE MATRICULA = @PE_MATRICULA;

                SELECT @CODMON_AL = A.CodMon#
                FROM ALUMNO A 
                INNER JOIN MONITOR M ON A.CodMon# = M.CodMon#;

                SELECT @TOTAL = COUNT(Num_Prac)
                FROM Practica P 
                INNER JOIN Alumno A ON P.CodAl# = A.CodAl#
                WHERE A.CodAl# = @CODMON_AL;
            END
        END
    END;

Ejercicio 3: Reasignación de Coche a Monitor según Carga de Alumnos

Enunciado: Crear un procedimiento almacenado que reciba el DNI de un monitor y la matrícula de un vehículo. Si el monitor está asignado a 15 alumnos, se debe modificar el vehículo asignado al monitor por el indicado por teclado. Validar que el DNI y la matrícula no estén vacíos y que ambos existan en la base de datos, mostrando los errores pertinentes por pantalla.

CREATE PROCEDURE proc_3
    @PE_DNI VARCHAR(8),
    @PE_MATRICULA CHAR(6)
AS
    DECLARE @PE_CODMON INT
    DECLARE @PE_TOTAL INT
    DECLARE @PE_MATRICULA_MON INT

    IF (@PE_DNI = '' OR @PE_MATRICULA = '')
    BEGIN
        PRINT 'ERROR EN LOS CAMPOS';
    END
    ELSE
    BEGIN
        IF (@PE_DNI NOT IN (SELECT DNI FROM MONITOR))
        BEGIN
            PRINT 'NO EXISTE';
        END
        ELSE
        BEGIN
            IF (@PE_MATRICULA NOT IN (SELECT MATRICULA FROM COCHE))
            BEGIN
                PRINT 'NO EXISTE';
            END
            ELSE
            BEGIN
                SELECT @PE_MATRICULA_MON = CodCoche#
                FROM COCHE
                WHERE MATRICULA = @PE_MATRICULA;

                SELECT @PE_CODMON = M.CodMon#
                FROM MONITOR M
                WHERE DNI = @PE_DNI;

                SELECT @PE_TOTAL = COUNT(CodAl#)
                FROM ALUMNO A 
                INNER JOIN MONITOR M ON A.CodMon# = M.CodMon#
                WHERE A.CodAl# = @PE_CODMON;

                IF (@PE_TOTAL < 15)
                BEGIN
                    UPDATE COCHE
                    SET CodCoche# = @PE_MATRICULA_MON
                    WHERE CodCoche# = (
                        SELECT CodCoche#
                        FROM MONITOR
                        WHERE MATRICULA = @PE_MATRICULA
                    );
                END
            END
        END
    END;

Ejercicio 4: Trigger para Reinicio de Kilómetros al Asignar Vehículo

Enunciado: Crear un trigger que, al asignar un coche a un monitor en una inserción, reinicie sus kilómetros a 0. Se incluye la sentencia de prueba correspondiente.

CREATE TRIGGER T1
ON MONITOR
FOR INSERT
AS
    UPDATE COCHE
    SET KMS = 0
    WHERE CodCOCHE# = (SELECT CodCOCHE# FROM inserted);

-- Inserción de prueba:
INSERT INTO MONITOR VALUES (50, '45421454s', 'LUIS', 'ESTRELLA', '10-1-1889', '658974521', 15);

Ejercicio 5: Cursor para Ajuste Dinámico de Precios según Tipo de Carnet

Enunciado: Implementar un cursor que modifique el precio de las clases prácticas: si el carnet del alumno es de tipo A o B se incrementa el precio un 10%, y si es de tipo C o D se le descuenta un 10%.

DECLARE @TIPO AS CHAR
DECLARE @CODAL AS INT

DECLARE CUR_CARNET CURSOR FOR 
    SELECT TIPOCARNET, CodAl# 
    FROM ALUMNO 
    WHERE Tipocarnet LIKE 'A' 
       OR Tipocarnet LIKE 'B' 
       OR Tipocarnet LIKE 'C' 
       OR Tipocarnet LIKE 'D'

OPEN CUR_CARNET
FETCH NEXT FROM CUR_CARNET INTO @TIPO, @CODAL

WHILE (@@FETCH_STATUS = 0)
BEGIN
    IF (@TIPO LIKE 'A' OR @TIPO LIKE 'B')
    BEGIN
        UPDATE PRACTICA
        SET Precio = Precio + (Precio * 0.1)
        WHERE CodAl# = @CODAL;
    END
    ELSE
    BEGIN
        UPDATE PRACTICA
        SET Precio = Precio - (Precio * 0.1)
        WHERE CodAl# = @CODAL;
    END

    FETCH NEXT FROM CUR_CARNET INTO @TIPO, @CODAL
END

CLOSE CUR_CARNET
DEALLOCATE CUR_CARNET

Ejercicio 6: Consulta de Alumnos por Matrícula con Validaciones

Enunciado: Crear un procedimiento almacenado que reciba una matrícula y devuelva la cantidad de alumnos que utilizan dicho vehículo, realizando las comprobaciones de existencia pertinentes.

ALTER PROCEDURE PROCEX
    @PE_MATRICULA CHAR(8)
AS
    DECLARE @CODMON_COCHE INT
    DECLARE @TOTAL INT

    IF (@PE_MATRICULA = '')
    BEGIN
        PRINT 'CAMPO INCORRECTO';
    END
    ELSE
    BEGIN
        IF (@PE_MATRICULA NOT IN (SELECT MATRICULA FROM COCHE))
        BEGIN
            PRINT 'NO EXISTE EN LA BASE DE DATOS';
        END
        ELSE
        BEGIN
            SELECT @CODMON_COCHE = CodMon#
            FROM COCHE C 
            INNER JOIN MONITOR M ON C.CodCOCHE# = M.CodCoche#
            WHERE Matricula = @PE_MATRICULA;

            SELECT COUNT(CodAL#)
            FROM ALUMNO A 
            INNER JOIN MONITOR M ON A.CodMon# = M.CodMon#
            WHERE A.CodMon# = @CODMON_COCHE;
        END
    END;

-- Ejecución de prueba:
EXEC PROCEX 'BBB0000';

Ejercicio 7: Procedimiento Almacenado de Cambio de Coche por Condición de Alumnos

Enunciado: Procedimiento almacenado que, tras validar DNI del monitor y matrícula introducida, evalúa si el monitor cuenta con un número determinado de alumnos asignados para actualizar su vehículo.

ALTER PROCEDURE PROC4
    @PE_DNI VARCHAR(8),
    @PE_MATRICULA CHAR(7)
AS
    DECLARE @CODMON INT
    DECLARE @TOTAL INT
    DECLARE @CODIGO_COCHE INT

    IF (@PE_DNI = '' OR @PE_MATRICULA = '')
    BEGIN
        PRINT 'CAMPOS INCORRECTOS';
    END
    ELSE
    BEGIN
        IF (@PE_DNI NOT IN (SELECT DNI FROM MONITOR))
        BEGIN
            PRINT 'NO EXISTE EN BD';
        END
        ELSE
        BEGIN
            IF (@PE_MATRICULA NOT IN (SELECT MATRICULA FROM COCHE))
            BEGIN
                PRINT 'NO EXISTE EN LA BD';
            END
            ELSE
            BEGIN
                SELECT @CODIGO_COCHE = CodCoche#
                FROM COCHE
                WHERE Matricula = @PE_MATRICULA;

                SELECT @CODMON = CodMon#
                FROM MONITOR
                WHERE DNI = @PE_DNI;

                SELECT @TOTAL = COUNT(CodAl#)
                FROM MONITOR M 
                INNER JOIN ALUMNO A ON M.CodMon# = A.CodMon#
                WHERE M.CodMon# = @CODMON;

                IF (@TOTAL = 10)
                BEGIN
                    UPDATE MONITOR
                    SET CodCoche# = @CODIGO_COCHE
                    WHERE CodCoche# = (
                        SELECT CodCoche#
                        FROM MONITOR
                        WHERE CodMon# = @CODMON
                    );
                END
            END
        END
    END;

-- Ejecución de prueba:
EXEC PROC4 '33333333', 'BBB0000';

Descargar

PDF Word HTML