# Bitácora de Sesión
Fecha: 22/04/2026
Inicio: [20:00] | Fin: [22:00] || Total:
[2 horas]
Presentes: Matías Benavides Sandoval
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
¿QUÉ HICIMOS HOY?
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- Se completó y validó el SP de listado con filtro:
sp_GetEmpleados.
- Se ajustó la lógica de normalización y clasificación del
filtro para cumplir la especificación:
- vacío o espacios -> todos
- solo números -> cédula
- letras/espacios -> nombre
- Se incorporó bitácora para consultas por filtro de nombre
y cédula.
- Se cambió la búsqueda por cédula a búsqueda aproximada con
LIKE
- Se hicieron pruebas reales para los casos: vacío, nombre, cédula y mixto.
- Se estandarizaron TODOS los SPs del proyecto con
convención de parámetros in/out y con un solo DECLARE por SP.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PROBLEMAS ENCONTRADOS Y CÓMO SE RESOLVIERON
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1) Error: Invalid column name IdTipoEvento
- Causa: en TipoEvento la PK real es id, no IdTipoEvento.
- Antes:
SELECT @idTipoEventoNombre = IdTipoEvento FROM
TipoEvento WHERE Nombre = 'Consulta con filtro de nombre';
- Después:
SELECT @idTipoEventoNombre = id FROM
TipoEvento WHERE Nombre = 'Consulta con filtro de nombre';
2) Error: Invalid column name Activo
- Causa: la columna correcta en Empleado es EsActivo.
- Antes:
WHERE Activo = 1
- Después:
WHERE EsActivo = 1
3) Error: Incorrect syntax near WHERE
- Causa: en el SELECT del filtro nombre había dos WHERE
consecutivos.
- Antes:
WHERE (Nombre LIKE ...)
WHERE EsActivo = 1
- Después:
WHERE (Nombre LIKE ...)
AND EsActivo = 1
4) Error al recompilar sp_InsertarEmpleado tras refactor
masivo
- Mensaje observado: Invalid column name
'FechaContrataci(aca aparecia un simbolo raro)n'
- Causa: tema de codificación/acento al referenciar
explícitamente la columna con tilde durante el refactor.
- Antes:
INSERT INTO Empleado (idPuesto,
ValorDocumentoIdentidad, Nombre, [FechaContratación], SaldoVacaciones,
EsActivo)
VALUES (...)
- Después:
INSERT INTO Empleado
VALUES (@inIdPuesto,
@inValorDocumentoIdentidad, @inNombre, CAST(GETDATE() AS DATE), 0.00, 1);
- Resultado: recompilación exitosa.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
DUDAS Y DIVERGENCIAS DE CRITERIO
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- Se confirmó con especificación que la búsqueda por cédula
debe ser aproximada, no exacta.
- Se decidió fallback para filtro mixto (ejemplo A1): tratar
como nombre para no bloquear al usuario.
- Se confirmó que la trazabilidad en este módulo usa dos
tipos de evento:
- Consulta con filtro de nombre
- Consulta con filtro de cedula
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
AVANCE DEL CÓDIGO
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
USE VacacionesDB;
GO
-- =====================================================
-- SP 4: Obtener lista de empleados
-- =====================================================
DROP PROCEDURE IF EXISTS sp_GetEmpleados;
GO
CREATE PROCEDURE sp_GetEmpleados
@outResultCode INT OUTPUT,
@inFiltro VARCHAR(128) = NULL,
@inUsername VARCHAR(128) = NULL,
@inIpPostIn VARCHAR(64) = NULL,
@inPostTime DATETIME = NULL
AS
BEGIN
SET NOCOUNT ON;
DECLARE @filtroNomvbrePuesto VARCHAR(128),
@tipoFiltro VARCHAR(32),
@idUsuario INT,
@idTipoEventoNombre INT,
@idTipoEventoCedula INT;
BEGIN TRY
-- Normalizar
SET @filtroNomvbrePuesto = LTRIM(RTRIM(ISNULL(@inFiltro, '')));
SET @filtroNomvbrePuesto = UPPER(@filtroNomvbrePuesto);
-- Clasificar filtro
IF @filtroNomvbrePuesto = ''
SET @tipoFiltro = 'TODOS';
ELSE IF PATINDEX('%[^0-9]%', @filtroNomvbrePuesto) = 0
SET @tipoFiltro = 'CEDULA';
ELSE IF PATINDEX('%[^A-Z ]%', @filtroNomvbrePuesto) = 0
SET @tipoFiltro = 'NOMBRE_PUESTO';
ELSE
SET @tipoFiltro = 'NOMBRE_PUESTO';
-- Obtener usuario
SELECT @idUsuario = Id FROM [dbo].[Usuario] WHERE Username = @inUsername;
-- Obtener tipos de eventos
SELECT @idTipoEventoNombre = id
FROM [dbo].[TipoEvento]
WHERE Nombre = 'Consulta con filtro de nombre';
SELECT @idTipoEventoCedula = Id
FROM [dbo].[TipoEvento]
WHERE Nombre = 'Consulta con filtro de cedula';
-- Log evento
IF @tipoFiltro = 'NOMBRE_PUESTO'
BEGIN
INSERT INTO [dbo].[BitacoraEvento] (IdUsuario, IdTipoEvento, Descripcion, IpPostIn, PostTime)
VALUES (@idUsuario, @idTipoEventoNombre, @filtroNomvbrePuesto, @inIpPostIn, @inPostTime);
END
ELSE IF @tipoFiltro = 'CEDULA'
BEGIN
INSERT INTO [dbo].[BitacoraEvento] (IdUsuario, IdTipoEvento, Descripcion, IpPostIn, PostTime)
VALUES (@idUsuario, @idTipoEventoCedula, @filtroNomvbrePuesto, @inIpPostIn, @inPostTime);
END
-- Obtener empleados
IF @tipoFiltro = 'NOMBRE_PUESTO'
SELECT Id, Nombre, ValorDocumentoIdentidad, idPuesto FROM [dbo].[Empleado]
WHERE (Nombre LIKE '%' + @filtroNomvbrePuesto + '%' OR
idPuesto IN (
SELECT Id
FROM [dbo].[Puesto]
WHERE Nombre LIKE '%' + @filtroNomvbrePuesto + '%'))
AND EsActivo = 1
ORDER BY Nombre ASC;
ELSE IF @tipoFiltro = 'CEDULA'
SELECT Id, Nombre, ValorDocumentoIdentidad, idPuesto FROM [dbo].[Empleado]
WHERE ValorDocumentoIdentidad LIKE '%' + @filtroNomvbrePuesto + '%'
AND EsActivo = 1
ORDER BY Nombre ASC;
ELSE IF @tipoFiltro = 'TODOS'
SELECT Id, Nombre, ValorDocumentoIdentidad, idPuesto FROM [dbo].[Empleado]
WHERE EsActivo = 1
ORDER BY Nombre ASC;
SET @outResultCode = 0;
END TRY
BEGIN CATCH
INSERT INTO DBError (UserName, Number, State, Severity, Line, [Procedure], Message, DateTime)
VALUES (
ISNULL(@inUsername, SYSTEM_USER),
ERROR_NUMBER(),
CAST(ERROR_STATE() AS VARCHAR(32)),
CAST(ERROR_SEVERITY() AS VARCHAR(32)),
ERROR_LINE(),
ISNULL(ERROR_PROCEDURE(), 'sp_GetEmpleados'),
ERROR_MESSAGE(),
GETDATE()
);
SET @outResultCode = 50008;
END CATCH
END;
USE VacacionesDB;
GO
-- =====================================================
-- SP 4: Obtener lista de empleados
-- =====================================================
DROP PROCEDURE IF EXISTS sp_GetEmpleados;
GO
CREATE PROCEDURE sp_GetEmpleados
@outResultCode INT OUTPUT,
@inFiltro VARCHAR(128) = NULL,
@inUsername VARCHAR(128) = NULL,
@inIpPostIn VARCHAR(64) = NULL,
@inPostTime DATETIME = NULL
AS
BEGIN
SET NOCOUNT ON;
DECLARE @filtroNomvbrePuesto VARCHAR(128),
@tipoFiltro VARCHAR(32),
@idUsuario INT,
@idTipoEventoNombre INT,
@idTipoEventoCedula INT;
BEGIN TRY
-- Normalizar
SET @filtroNomvbrePuesto = LTRIM(RTRIM(ISNULL(@inFiltro, '')));
SET @filtroNomvbrePuesto = UPPER(@filtroNomvbrePuesto);
-- Clasificar filtro
IF @filtroNomvbrePuesto = ''
SET @tipoFiltro = 'TODOS';
ELSE IF PATINDEX('%[^0-9]%', @filtroNomvbrePuesto) = 0
SET @tipoFiltro = 'CEDULA';
ELSE IF PATINDEX('%[^A-Z ]%', @filtroNomvbrePuesto) = 0
SET @tipoFiltro = 'NOMBRE_PUESTO';
ELSE
SET @tipoFiltro = 'NOMBRE_PUESTO';
-- Obtener usuario
SELECT @idUsuario = Id FROM [dbo].[Usuario] WHERE Username = @inUsername;
-- Obtener tipos de eventos
SELECT @idTipoEventoNombre = id
FROM [dbo].[TipoEvento]
WHERE Nombre = 'Consulta con filtro de nombre';
SELECT @idTipoEventoCedula = Id
FROM [dbo].[TipoEvento]
WHERE Nombre = 'Consulta con filtro de cedula';
-- Log evento
IF @tipoFiltro = 'NOMBRE_PUESTO'
BEGIN
INSERT INTO [dbo].[BitacoraEvento] (IdUsuario, IdTipoEvento, Descripcion, IpPostIn, PostTime)
VALUES (@idUsuario, @idTipoEventoNombre, @filtroNomvbrePuesto, @inIpPostIn, @inPostTime);
END
ELSE IF @tipoFiltro = 'CEDULA'
BEGIN
INSERT INTO [dbo].[BitacoraEvento] (IdUsuario, IdTipoEvento, Descripcion, IpPostIn, PostTime)
VALUES (@idUsuario, @idTipoEventoCedula, @filtroNomvbrePuesto, @inIpPostIn, @inPostTime);
END
-- Obtener empleados
IF @tipoFiltro = 'NOMBRE_PUESTO'
SELECT Id, Nombre, ValorDocumentoIdentidad, idPuesto FROM [dbo].[Empleado]
WHERE (Nombre LIKE '%' + @filtroNomvbrePuesto + '%' OR
idPuesto IN (
SELECT Id
FROM [dbo].[Puesto]
WHERE Nombre LIKE '%' + @filtroNomvbrePuesto + '%'))
AND EsActivo = 1
ORDER BY Nombre ASC;
ELSE IF @tipoFiltro = 'CEDULA'
SELECT Id, Nombre, ValorDocumentoIdentidad, idPuesto FROM [dbo].[Empleado]
WHERE ValorDocumentoIdentidad LIKE '%' + @filtroNomvbrePuesto + '%'
AND EsActivo = 1
ORDER BY Nombre ASC;
ELSE IF @tipoFiltro = 'TODOS'
SELECT Id, Nombre, ValorDocumentoIdentidad, idPuesto FROM [dbo].[Empleado]
WHERE EsActivo = 1
ORDER BY Nombre ASC;
SET @outResultCode = 0;
END TRY
BEGIN CATCH
INSERT INTO DBError (UserName, Number, State, Severity, Line, [Procedure], Message, DateTime)
VALUES (
ISNULL(@inUsername, SYSTEM_USER),
ERROR_NUMBER(),
CAST(ERROR_STATE() AS VARCHAR(32)),
CAST(ERROR_SEVERITY() AS VARCHAR(32)),
ERROR_LINE(),
ISNULL(ERROR_PROCEDURE(), 'sp_GetEmpleados'),
ERROR_MESSAGE(),
GETDATE()
);
SET @outResultCode = 50008;
END CATCH
END;
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
MORALEJAS / BUENAS PRÁCTICAS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- Revisar nombres reales de columnas.
- Evitar hardcodear ids de eventos, resolver por Nombre en
TipoEvento.
- Mantener consistencia de parámetros in/out.
- Probar siempre con casos funcionales reales y también
casos borde.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PRÓXIMA SESIÓN: ¿QUÉ SIGUE?
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- Empezar: implementar endpoint GET
/api/empleados que llame sp_GetEmpleados.
- Luego conectar la pantalla de listado/filtro con ese
endpoint.
Comentarios
Publicar un comentario