Entrada 5 (Sps InsertEmpleado y DeleteEmpleado)

 Fecha: 17/04/2026 y 18/04/2026

Inicio: [23:00] del 17 | Fin: [00:50] del 18 || Total: [1 hora y 50 minutos]

Presentes: Sebastián Ramírez Abarca

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
¿QUÉ HICIMOS HOY?
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Se avanzó con los store procedures, se terminaron y probaron en local sp_InsertEmpleado y sp_DeleteEmpleado (borrado lógico)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PROBLEMAS ENCONTRADOS Y CÓMO SE RESOLVIERON
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. Bloqueo haciendo sp_InsertEmpleado, no supe cómo implementar el insert a la tabla DBError.
Solución: Tras tiempo de vergüenza terminé por preguntarle a mi compañero y me explicó usando el SP que él había hecho anteriormente como ejemplo.

2. Me sucedió error de Windows mientras trabajaba en sp_DeleteEmpleado.
Solución: Resultó que tenía programada una actualización para las 00:20 y sucedió un error que causó una pantalla negra con el mensaje "your device ran into a problem and needs to restart", tras tiempo de espera sin avance del reinicio presioné el botón de apagado para que retrocediera la actualización y ya pude seguir.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
DUDAS Y DIVERGENCIAS DE CRITERIO
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. Cómo implementar el insert a la tabla DBError.
2. No hubo divergencias en esta sesión.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
AVANCE DEL CÓDIGO
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
sp_InsertEmpleado:
USE VacacionesDB;
GO

-- =====================================================
-- SP: Insertar un nuevo empleado
-- =====================================================
DROP PROCEDURE IF EXISTS sp_InsertarEmpleado;
GO

CREATE PROCEDURE sp_InsertarEmpleado
    @ValorDocumentoIdentidad VARCHAR(32),
    @Nombre                  VARCHAR(128),
    @idPuesto                INT,
    @idUsuario               INT,
    @IpPostIn                VARCHAR(64),
    @PostTime                DATETIME,
    @outResultCode           INT OUTPUT
AS
BEGIN
    SET NOCOUNT ON;
    SET XACT_ABORT ON;

    DECLARE @NombrePuesto   VARCHAR(128);
    DECLARE @idTipoEventoOk INT;
    DECLARE @idTipoEventoFail INT;
    DECLARE @Descripcion    VARCHAR(512);

    SET @outResultCode = 0;

    BEGIN TRY

        -- Obtener id de TipoEvento para bitácora
        SELECT @idTipoEventoOk   = id FROM TipoEvento WHERE Nombre = 'Insercion exitosa';
        SELECT @idTipoEventoFail = id FROM TipoEvento WHERE Nombre = 'Insercion no exitosa';

        -- Obtener nombre del puesto para bitácora
        SELECT @NombrePuesto = Nombre
        FROM Puesto
        WHERE id = @idPuesto;

        -- Validar: ValorDocumentoIdentidad duplicado
        IF EXISTS (
            SELECT 1 FROM Empleado
            WHERE ValorDocumentoIdentidad = @ValorDocumentoIdentidad
              AND EsActivo = 1
        )
        BEGIN
            SET @outResultCode = 50004;

            SET @Descripcion =
                'Error: ' + (SELECT Descripcion FROM Error WHERE Codigo = 50004)
                + ' | ValorDocumentoIdentidad: '    + @ValorDocumentoIdentidad
                + ' | Nombre: ' + @Nombre
                + ' | Puesto: ' + ISNULL(@NombrePuesto, '');

            INSERT INTO BitacoraEvento (idTipoEvento, Descripcion, idUsuario, IpPostIn, PostTime)
            VALUES (@idTipoEventoFail, @Descripcion, @idUsuario, @IpPostIn, @PostTime);

            RETURN;
        END

        -- Validar: Nombre duplicado
        IF EXISTS (
            SELECT 1 FROM Empleado
            WHERE Nombre = @Nombre
              AND EsActivo = 1
        )
        BEGIN
            SET @outResultCode = 50005;

            SET @Descripcion =
                'Error: ' + (SELECT Descripcion FROM Error WHERE Codigo = 50005)
                + ' | ValorDocumentoIdentidad: '    + @ValorDocumentoIdentidad
                + ' | Nombre: ' + @Nombre
                + ' | Puesto: ' + ISNULL(@NombrePuesto, '');

            INSERT INTO BitacoraEvento (idTipoEvento, Descripcion, idUsuario, IpPostIn, PostTime)
            VALUES (@idTipoEventoFail, @Descripcion, @idUsuario, @IpPostIn, @PostTime);

            RETURN;
        END

        -- Insertar empleado
        BEGIN TRANSACTION;

            INSERT INTO Empleado (idPuesto, ValorDocumentoIdentidad, Nombre, FechaContratación, SaldoVacaciones, EsActivo)
            VALUES (@idPuesto, @ValorDocumentoIdentidad, @Nombre, CAST(GETDATE() AS DATE), 0.00, 1);

            -- Bitácora: Inserción exitosa
            SET @Descripcion =
                'ValorDocumentoIdentidad: '     + @ValorDocumentoIdentidad
                + ' | Nombre: ' + @Nombre
                + ' | Puesto: ' + ISNULL(@NombrePuesto, '');

            INSERT INTO BitacoraEvento (idTipoEvento, Descripcion, idUsuario, IpPostIn, PostTime)
            VALUES (@idTipoEventoOk, @Descripcion, @idUsuario, @IpPostIn, @PostTime);

        COMMIT TRANSACTION;

        SET @outResultCode = 0;

    END TRY
    BEGIN CATCH

        IF @@TRANCOUNT > 0
            ROLLBACK TRANSACTION;

        -- Registrar en DBError
        INSERT INTO DBError (UserName, Number, State, Severity, Line, [Procedure], Message, DateTime)
        VALUES (
            SYSTEM_USER,
            ERROR_NUMBER(),
            CAST(ERROR_STATE()    AS VARCHAR(32)),
            CAST(ERROR_SEVERITY() AS VARCHAR(32)),
            ERROR_LINE(),
            ISNULL(ERROR_PROCEDURE(), 'sp_InsertarEmpleado'),
            ERROR_MESSAGE(),
            GETDATE()
        );

        -- Bitácora: Inserción no exitosa por error de BD
        SET @Descripcion =
            'Error: ' + (SELECT Descripcion FROM Error WHERE Codigo = 50008)
            + ' | ValorDocumentoIdentidad: '    + @ValorDocumentoIdentidad
            + ' | Nombre: ' + @Nombre
            + ' | Puesto: ' + ISNULL(@NombrePuesto, '');

        INSERT INTO BitacoraEvento (idTipoEvento, Descripcion, idUsuario, IpPostIn, PostTime)
        VALUES (@idTipoEventoFail, @Descripcion, @idUsuario, @IpPostIn, @PostTime);

        SET @outResultCode = 50008;

    END CATCH
END;
GO
sp_DeleteEmpleado:
USE VacacionesDB;
GO

-- =====================================================
-- SP: Borrado lógico de un empleado
-- =====================================================
DROP PROCEDURE IF EXISTS sp_DeleteEmpleado;
GO

CREATE PROCEDURE sp_DeleteEmpleado
    @ValorDocumentoIdentidad VARCHAR(32),
    @idUsuario               INT,
    @IpPostIn                VARCHAR(64),
    @PostTime                DATETIME,
    @Confirmado              BIT,
    @outResultCode           INT OUTPUT
AS
BEGIN
    SET NOCOUNT ON;
    SET XACT_ABORT ON;

    DECLARE @idEmpleado       INT;
    DECLARE @NombreEmpleado   VARCHAR(128);
    DECLARE @NombrePuesto     VARCHAR(128);
    DECLARE @SaldoVacaciones  DECIMAL(10,2);
    DECLARE @idTipoEventoIntento  INT;
    DECLARE @idTipoEventoBorrado  INT;
    DECLARE @Descripcion      VARCHAR(512);

    SET @outResultCode = 0;

    BEGIN TRY

        -- Obtener id de TipoEvento
        SELECT @idTipoEventoIntento = id FROM TipoEvento WHERE Nombre = 'Intento de borrado';
        SELECT @idTipoEventoBorrado = id FROM TipoEvento WHERE Nombre = 'Borrado exitoso';

        -- Obtener datos del empleado
        SELECT
            @idEmpleado      = e.id,
            @NombreEmpleado  = e.Nombre,
            @SaldoVacaciones = e.SaldoVacaciones,
            @NombrePuesto    = p.Nombre
        FROM Empleado e
        INNER JOIN Puesto p ON e.idPuesto = p.id
        WHERE e.ValorDocumentoIdentidad = @ValorDocumentoIdentidad
          AND e.EsActivo = 1;

        -- Si no existe el empleado
        IF @idEmpleado IS NULL
        BEGIN
            SET @outResultCode = 50008;
            RETURN;
        END

        -- Descripción
        SET @Descripcion =
            'ValorDocumentoIdentidad: '          + @ValorDocumentoIdentidad
            + ' | Nombre: '  + @NombreEmpleado
            + ' | Puesto: '  + @NombrePuesto
            + ' | Saldo: '   + CAST(@SaldoVacaciones AS VARCHAR(20));

        -- Si el usuario NO confirmó entonces registrar intento y salir
        IF @Confirmado = 0
        BEGIN
            INSERT INTO BitacoraEvento (idTipoEvento, Descripcion, idUsuario, IpPostIn, PostTime)
            VALUES (@idTipoEventoIntento, @Descripcion, @idUsuario, @IpPostIn, @PostTime);

            SET @outResultCode = 0;
            RETURN;
        END

        -- Si confirmó entonces hacer borrado lógico
        BEGIN TRANSACTION;

            UPDATE Empleado
            SET EsActivo = 0
            WHERE id = @idEmpleado;

            INSERT INTO BitacoraEvento (idTipoEvento, Descripcion, idUsuario, IpPostIn, PostTime)
            VALUES (@idTipoEventoBorrado, @Descripcion, @idUsuario, @IpPostIn, @PostTime);

        COMMIT TRANSACTION;

        SET @outResultCode = 0;

    END TRY
    BEGIN CATCH

        IF @@TRANCOUNT > 0
            ROLLBACK TRANSACTION;

        INSERT INTO DBError (UserName, Number, State, Severity, Line, [Procedure], Message, DateTime)
        VALUES (
            SYSTEM_USER,
            ERROR_NUMBER(),
            CAST(ERROR_STATE()    AS VARCHAR(32)),
            CAST(ERROR_SEVERITY() AS VARCHAR(32)),
            ERROR_LINE(),
            ISNULL(ERROR_PROCEDURE(), 'sp_DeleteEmpleado'),
            ERROR_MESSAGE(),
            GETDATE()
        );

        SET @outResultCode = 50008;

    END CATCH
END;
GO
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
MORALEJAS / BUENAS PRÁCTICAS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. Aunque dé vergüenza, si se requiere ayuda y un compañero te la puede brindar dar el primer paso de pedir ayuda,
2. Planear que tiene que tener cada SP antes de empezar a codear.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PRÓXIMA SESIÓN: ¿QUÉ SIGUE?
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- Realizar sp_UpdateEmpleado para actualizar información de empleados.
- Realizar sp_GetEmpleado para obtener la información de un empleado.

Comentarios

Entradas más populares de este blog

Entrada 16 (Controlador de movimientos)

Entrada 20 (Lógica de insertarMovimientos, conectarla y probarla)

Entrada 21 (Análisis de resultados)