Files
Plataforma-de-desarrolladores/Bitacora_Procedimientos.sql
Jorge Luis caudillo esparza 45ce71c7da BITACORA FEA
2026-08-14 05:43:41 -07:00

1709 lines
56 KiB
Transact-SQL

/*
Configuración y procedimientos actuales de la bitácora.
La bitácora participa en la transacción ambiental de la operación principal.
*/
SET NOCOUNT ON;
GO
IF COL_LENGTH('dbo.Bit_Campos', 'TipoDatoSQL') IS NULL
BEGIN
ALTER TABLE dbo.Bit_Campos
ADD TipoDatoSQL varchar(128) COLLATE Modern_Spanish_CS_AS NULL;
END;
GO
IF COL_LENGTH('dbo.Bit_Campos', 'CveTablaReferencia') IS NULL
BEGIN
ALTER TABLE dbo.Bit_Campos
ADD CveTablaReferencia int NULL;
END;
GO
IF COL_LENGTH('dbo.Bit_Campos', 'CveCampoMostrarReferencia') IS NULL
BEGIN
ALTER TABLE dbo.Bit_Campos
ADD CveCampoMostrarReferencia int NULL;
END;
GO
IF NOT EXISTS
(
SELECT 1
FROM sys.check_constraints
WHERE parent_object_id = OBJECT_ID('dbo.Bit_Campos')
AND name = 'CK_Bit_Campos_ReferenciaCompleta'
)
BEGIN
ALTER TABLE dbo.Bit_Campos WITH CHECK
ADD CONSTRAINT CK_Bit_Campos_ReferenciaCompleta
CHECK
(
(CveTablaReferencia IS NULL AND CveCampoMostrarReferencia IS NULL)
OR
(CveTablaReferencia IS NOT NULL AND CveCampoMostrarReferencia IS NOT NULL)
);
ALTER TABLE dbo.Bit_Campos
CHECK CONSTRAINT CK_Bit_Campos_ReferenciaCompleta;
END;
GO
IF NOT EXISTS
(
SELECT 1
FROM sys.foreign_keys
WHERE parent_object_id = OBJECT_ID('dbo.Bit_Campos')
AND name = 'FK_Bit_Campos_TablaReferencia'
)
BEGIN
ALTER TABLE dbo.Bit_Campos WITH CHECK
ADD CONSTRAINT FK_Bit_Campos_TablaReferencia
FOREIGN KEY (CveTablaReferencia)
REFERENCES dbo.Bit_Tablas (CveTabla);
ALTER TABLE dbo.Bit_Campos
CHECK CONSTRAINT FK_Bit_Campos_TablaReferencia;
END;
GO
IF NOT EXISTS
(
SELECT 1
FROM sys.foreign_keys
WHERE parent_object_id = OBJECT_ID('dbo.Bit_Campos')
AND name = 'FK_Bit_Campos_CampoMostrarReferencia'
)
BEGIN
ALTER TABLE dbo.Bit_Campos WITH CHECK
ADD CONSTRAINT FK_Bit_Campos_CampoMostrarReferencia
FOREIGN KEY (CveCampoMostrarReferencia)
REFERENCES dbo.Bit_Campos (CveCampo);
ALTER TABLE dbo.Bit_Campos
CHECK CONSTRAINT FK_Bit_Campos_CampoMostrarReferencia;
END;
GO
IF COL_LENGTH('dbo.Bit_BitacoraRelaciones', 'VisibleDesarrollador') IS NULL
BEGIN
ALTER TABLE dbo.Bit_BitacoraRelaciones
ADD VisibleDesarrollador bit NOT NULL
CONSTRAINT DF_Bit_BitacoraRelaciones_VisibleDesarrollador
DEFAULT (0);
END;
GO
IF NOT EXISTS
(
SELECT 1
FROM sys.indexes
WHERE object_id = OBJECT_ID('dbo.Bit_BitacoraRelaciones')
AND name = 'IX_Bit_BitacoraRelaciones_Filtro'
)
BEGIN
CREATE NONCLUSTERED INDEX IX_Bit_BitacoraRelaciones_Filtro
ON dbo.Bit_BitacoraRelaciones
(
CveTablaRelacionada,
CveCampoRelacion,
ValorRelacionNumero,
VisibleDesarrollador,
CveBitacora
)
INCLUDE
(
ValorRelacionTexto,
LlaveRegistroRelacionada
);
END;
GO
IF NOT EXISTS
(
SELECT 1
FROM sys.indexes
WHERE object_id = OBJECT_ID('dbo.Bit_BitacoraRelaciones')
AND name = 'IX_Bit_BitacoraRelaciones_FiltroTexto'
)
BEGIN
CREATE NONCLUSTERED INDEX IX_Bit_BitacoraRelaciones_FiltroTexto
ON dbo.Bit_BitacoraRelaciones
(
CveTablaRelacionada,
CveCampoRelacion,
ValorRelacionTexto,
VisibleDesarrollador,
CveBitacora
)
INCLUDE
(
ValorRelacionNumero,
LlaveRegistroRelacionada
);
END;
GO
DECLARE @Tablas TABLE
(
NombreTablaSQL varchar(128) COLLATE Modern_Spanish_CS_AS NOT NULL,
NombreMostrar varchar(150) COLLATE Modern_Spanish_CS_AS NOT NULL,
Descripcion varchar(500) COLLATE Modern_Spanish_CS_AS NULL,
NombreCampoLlaveSQL varchar(128) COLLATE Modern_Spanish_CS_AS NULL
);
INSERT INTO @Tablas
(
NombreTablaSQL,
NombreMostrar,
Descripcion,
NombreCampoLlaveSQL
)
VALUES
('Clientes', 'Clientes', 'Clientes propietarios de la información.', 'CveCliente'),
('Fraccionamientos', 'Fraccionamientos', 'Catálogo de fraccionamientos.', 'CveFraccionamiento'),
('Fraccionamientos_Estatus', 'Estatus de fraccionamiento', 'Catálogo de estatus de fraccionamientos.', 'CveEstatus'),
('FraccionamientosEtapas', 'Etapas', 'Etapas de los fraccionamientos.', 'CveFraccionamientoEtapa'),
('FraccionamientosEtapasGIS', 'GIS de etapas', 'GIS asociado a las etapas.', 'CveFraccionamientoEtapaGIS'),
('FraccionamientosLotes', 'Lotes', 'Lotes de las etapas.', 'CveFraccionamientoLote'),
('Sis_Usuarios', 'Usuarios', 'Usuarios del sistema.', 'CveUsuario'),
('Sis_UsuariosClientes', 'Clientes por usuario', 'Asignaciones de clientes a usuarios.', NULL);
UPDATE T
SET
T.NombreMostrar = S.NombreMostrar,
T.Descripcion = S.Descripcion,
T.NombreCampoLlaveSQL = S.NombreCampoLlaveSQL,
T.Activo = 1,
T.FechaMod = GETDATE()
FROM dbo.Bit_Tablas AS T
INNER JOIN @Tablas AS S
ON S.NombreTablaSQL = T.NombreTablaSQL;
INSERT INTO dbo.Bit_Tablas
(
NombreTablaSQL,
NombreMostrar,
Descripcion,
NombreCampoLlaveSQL,
Activo
)
SELECT
S.NombreTablaSQL,
S.NombreMostrar,
S.Descripcion,
S.NombreCampoLlaveSQL,
1
FROM @Tablas AS S
WHERE NOT EXISTS
(
SELECT 1
FROM dbo.Bit_Tablas AS T
WHERE T.NombreTablaSQL = S.NombreTablaSQL
);
GO
DECLARE @Campos TABLE
(
NombreTablaSQL varchar(128) COLLATE Modern_Spanish_CS_AS NOT NULL,
NombreCampoSQL varchar(128) COLLATE Modern_Spanish_CS_AS NOT NULL,
NombreMostrar varchar(150) COLLATE Modern_Spanish_CS_AS NOT NULL,
MostrarEnBitacora bit NOT NULL
);
INSERT INTO @Campos
(
NombreTablaSQL,
NombreCampoSQL,
NombreMostrar,
MostrarEnBitacora
)
VALUES
('Clientes', 'CveCliente', 'Cliente', 0),
('Clientes', 'Nombre', 'Cliente', 1),
('Fraccionamientos', 'CveFraccionamiento', 'Clave de fraccionamiento', 0),
('Fraccionamientos', 'CveCliente', 'Cliente', 1),
('Fraccionamientos', 'Fraccionamiento', 'Fraccionamiento', 1),
('Fraccionamientos', 'Hectareas', 'Hectáreas', 1),
('Fraccionamientos', 'Ubicacion', 'Ubicación', 1),
('Fraccionamientos', 'CveEstatus', 'Estatus', 1),
('Fraccionamientos', 'EsActivo', 'Activo', 1),
('Fraccionamientos_Estatus', 'CveEstatus', 'Clave de estatus', 0),
('Fraccionamientos_Estatus', 'Estatus', 'Estatus', 1),
('FraccionamientosEtapas', 'CveFraccionamientoEtapa', 'Clave de etapa', 0),
('FraccionamientosEtapas', 'CveFraccionamiento', 'Fraccionamiento', 1),
('FraccionamientosEtapas', 'Etapa', 'Etapa', 1),
('FraccionamientosEtapas', 'Hectareas', 'Hectáreas', 1),
('FraccionamientosEtapas', 'Orden', 'Orden', 1),
('FraccionamientosEtapas', 'Avance', 'Avance', 1),
('FraccionamientosEtapas', 'EsActivo', 'Activo', 1),
('FraccionamientosEtapasGIS', 'CveFraccionamientoEtapaGIS', 'Clave de GIS', 0),
('FraccionamientosEtapasGIS', 'CveFraccionamientoEtapa', 'Etapa', 1),
('FraccionamientosEtapasGIS', 'Nombre', 'GIS', 1),
('FraccionamientosEtapasGIS', 'UrlVisualizacion', 'URL de visualización', 1),
('FraccionamientosLotes', 'CveFraccionamientoLote', 'Clave de lote', 0),
('FraccionamientosLotes', 'CveFraccionamientoEtapa', 'Etapa', 1),
('FraccionamientosLotes', 'Numero', 'Número', 1),
('FraccionamientosLotes', 'Tipo', 'Tipo', 1),
('FraccionamientosLotes', 'Calle', 'Calle', 1),
('FraccionamientosLotes', 'Catastro', 'Catastro', 1),
('FraccionamientosLotes', 'MetrosCuadrados', 'Metros cuadrados', 1),
('FraccionamientosLotes', 'Duplicador', 'Duplicador', 1),
('FraccionamientosLotes', 'EsActivo', 'Activo', 1),
('Sis_Usuarios', 'CveUsuario', 'Clave de usuario', 0),
('Sis_Usuarios', 'NombreUsuario', 'Usuario', 1),
('Sis_Usuarios', 'CorreoElectronico', 'Correo electrónico', 1),
('Sis_Usuarios', 'CveRol', 'Rol', 1),
('Sis_Usuarios', 'Activo', 'Activo', 1),
('Sis_Usuarios', 'DebeCambiarContrasena', 'Debe cambiar contraseña', 1),
('Sis_Usuarios', 'CorreoVerificado', 'Correo verificado', 1),
('Sis_UsuariosClientes', 'CveUsuario', 'Usuario', 1),
('Sis_UsuariosClientes', 'CveCliente', 'Cliente', 1),
('Sis_UsuariosClientes', 'Orden', 'Orden', 1),
('Sis_UsuariosClientes', 'EsPrincipal', 'Principal', 1),
('Sis_UsuariosClientes', 'Activo', 'Activo', 1);
UPDATE C
SET
C.NombreMostrar = S.NombreMostrar,
C.MostrarEnBitacora = S.MostrarEnBitacora,
C.TipoDatoSQL = TY.name COLLATE Modern_Spanish_CS_AS,
C.Activo = 1,
C.FechaMod = GETDATE()
FROM dbo.Bit_Campos AS C
INNER JOIN dbo.Bit_Tablas AS T
ON T.CveTabla = C.CveTabla
INNER JOIN @Campos AS S
ON S.NombreTablaSQL = T.NombreTablaSQL
AND S.NombreCampoSQL = C.NombreCampoSQL
INNER JOIN sys.schemas AS SC
ON SC.name = 'dbo'
INNER JOIN sys.tables AS ST
ON ST.schema_id = SC.schema_id
AND ST.name COLLATE Modern_Spanish_CS_AS = S.NombreTablaSQL
INNER JOIN sys.columns AS CO
ON CO.object_id = ST.object_id
AND CO.name COLLATE Modern_Spanish_CS_AS = S.NombreCampoSQL
INNER JOIN sys.types AS TY
ON TY.user_type_id = CO.user_type_id;
INSERT INTO dbo.Bit_Campos
(
CveTabla,
NombreCampoSQL,
NombreMostrar,
MostrarEnBitacora,
TipoDatoSQL,
Activo
)
SELECT
T.CveTabla,
S.NombreCampoSQL,
S.NombreMostrar,
S.MostrarEnBitacora,
TY.name COLLATE Modern_Spanish_CS_AS,
1
FROM @Campos AS S
INNER JOIN dbo.Bit_Tablas AS T
ON T.NombreTablaSQL = S.NombreTablaSQL
INNER JOIN sys.schemas AS SC
ON SC.name = 'dbo'
INNER JOIN sys.tables AS ST
ON ST.schema_id = SC.schema_id
AND ST.name COLLATE Modern_Spanish_CS_AS = S.NombreTablaSQL
INNER JOIN sys.columns AS CO
ON CO.object_id = ST.object_id
AND CO.name COLLATE Modern_Spanish_CS_AS = S.NombreCampoSQL
INNER JOIN sys.types AS TY
ON TY.user_type_id = CO.user_type_id
WHERE NOT EXISTS
(
SELECT 1
FROM dbo.Bit_Campos AS C
WHERE C.CveTabla = T.CveTabla
AND C.NombreCampoSQL = S.NombreCampoSQL
);
GO
DECLARE @ReferenciasCampos TABLE
(
NombreTablaOrigen varchar(128) COLLATE Modern_Spanish_CS_AS NOT NULL,
NombreCampoOrigen varchar(128) COLLATE Modern_Spanish_CS_AS NOT NULL,
NombreTablaReferencia varchar(128) COLLATE Modern_Spanish_CS_AS NOT NULL,
NombreCampoMostrarReferencia varchar(128) COLLATE Modern_Spanish_CS_AS NOT NULL
);
INSERT INTO @ReferenciasCampos
(
NombreTablaOrigen,
NombreCampoOrigen,
NombreTablaReferencia,
NombreCampoMostrarReferencia
)
VALUES
('Fraccionamientos', 'CveCliente', 'Clientes', 'Nombre'),
('Fraccionamientos', 'CveEstatus', 'Fraccionamientos_Estatus', 'Estatus'),
('FraccionamientosEtapas', 'CveFraccionamiento', 'Fraccionamientos', 'Fraccionamiento'),
('FraccionamientosEtapasGIS', 'CveFraccionamientoEtapa', 'FraccionamientosEtapas', 'Etapa'),
('FraccionamientosLotes', 'CveFraccionamientoEtapa', 'FraccionamientosEtapas', 'Etapa'),
('Sis_UsuariosClientes', 'CveUsuario', 'Sis_Usuarios', 'NombreUsuario'),
('Sis_UsuariosClientes', 'CveCliente', 'Clientes', 'Nombre');
UPDATE CO
SET
CO.CveTablaReferencia = TR.CveTabla,
CO.CveCampoMostrarReferencia = CM.CveCampo,
CO.FechaMod = GETDATE()
FROM dbo.Bit_Campos AS CO
INNER JOIN dbo.Bit_Tablas AS TOG
ON TOG.CveTabla = CO.CveTabla
INNER JOIN @ReferenciasCampos AS R
ON R.NombreTablaOrigen = TOG.NombreTablaSQL
AND R.NombreCampoOrigen = CO.NombreCampoSQL
INNER JOIN dbo.Bit_Tablas AS TR
ON TR.NombreTablaSQL = R.NombreTablaReferencia
AND TR.Activo = 1
INNER JOIN dbo.Bit_Campos AS CM
ON CM.CveTabla = TR.CveTabla
AND CM.NombreCampoSQL = R.NombreCampoMostrarReferencia
AND CM.MostrarEnBitacora = 1
AND CM.Activo = 1;
GO
CREATE OR ALTER PROCEDURE dbo.PA_Bit_BitacoraAdd
@NombreTablaSQL varchar(128),
@CveTipoMovimiento tinyint,
@CveDefinicionAccion int = NULL,
@CveUsuarioAutoriza int = NULL,
@FechaAutorizacion datetime = NULL,
@LlaveRegistro nvarchar(250),
@DescripcionMovimiento nvarchar(1000),
@RelacionesXml xml,
@CamposXml xml = NULL,
@DiscriminarCamposSinCambios bit = 1,
@DireccionIP varchar(50) = NULL,
@NombreEquipo varchar(150) = NULL,
@Modulo varchar(150) = NULL,
@CveUsuarioEjecuta int,
@ErrorMostrar varchar(max) OUTPUT,
@ErrorTipo int OUTPUT,
@Return bit OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SELECT
@ErrorMostrar = NULL,
@ErrorTipo = 0,
@Return = 0;
BEGIN TRY
DECLARE @CveTabla int;
SELECT @CveTabla = T.CveTabla
FROM dbo.Bit_Tablas AS T
WHERE T.NombreTablaSQL = @NombreTablaSQL COLLATE Modern_Spanish_CS_AS
AND T.Activo = 1;
IF @CveTabla IS NULL
BEGIN
SET @ErrorMostrar = 'La tabla indicada no está configurada para bitácora.';
SET @ErrorTipo = 2;
RETURN;
END;
IF NOT EXISTS
(
SELECT 1
FROM dbo.Bit_TiposMovimiento AS M
WHERE M.CveTipoMovimiento = @CveTipoMovimiento
)
BEGIN
SET @ErrorMostrar = 'El tipo de movimiento de bitácora no es válido.';
SET @ErrorTipo = 2;
RETURN;
END;
IF @CveDefinicionAccion IS NOT NULL
AND NOT EXISTS
(
SELECT 1
FROM dbo.Bit_DefinicionesAccion AS A
WHERE A.CveDefinicionAccion = @CveDefinicionAccion
AND A.CveTabla = @CveTabla
AND A.CveTipoMovimiento = @CveTipoMovimiento
AND A.Activo = 1
)
BEGIN
SET @ErrorMostrar = 'La definición de la acción no corresponde al movimiento.';
SET @ErrorTipo = 2;
RETURN;
END;
DECLARE @Relaciones TABLE
(
Orden int NOT NULL,
CveTipoRelacion tinyint NOT NULL,
NombreTablaSQL varchar(128) COLLATE Modern_Spanish_CS_AS NOT NULL,
NombreCampoSQL varchar(128) COLLATE Modern_Spanish_CS_AS NOT NULL,
Valor nvarchar(250) COLLATE Modern_Spanish_CS_AS NOT NULL,
VisibleDesarrollador bit NOT NULL,
DescripcionRelacion nvarchar(500) COLLATE Modern_Spanish_CS_AS NULL
);
INSERT INTO @Relaciones
(
Orden,
CveTipoRelacion,
NombreTablaSQL,
NombreCampoSQL,
Valor,
VisibleDesarrollador,
DescripcionRelacion
)
SELECT
R.value('@Orden', 'int'),
R.value('@CveTipoRelacion', 'tinyint'),
R.value('@NombreTablaSQL', 'varchar(128)'),
R.value('@NombreCampoSQL', 'varchar(128)'),
R.value('@Valor', 'nvarchar(250)'),
R.value('@VisibleDesarrollador', 'bit'),
NULLIF(R.value('@DescripcionRelacion', 'nvarchar(500)'), '')
FROM @RelacionesXml.nodes('/Relaciones/Relacion') AS X(R);
IF NOT EXISTS (SELECT 1 FROM @Relaciones)
BEGIN
SET @ErrorMostrar = 'La bitácora debe incluir al menos una relación.';
SET @ErrorTipo = 2;
RETURN;
END;
DECLARE @RelacionesResueltas TABLE
(
Orden int NOT NULL,
CveTipoRelacion tinyint NOT NULL,
CveTabla int NOT NULL,
CveCampo int NOT NULL,
NombreTablaSQL varchar(128) COLLATE Modern_Spanish_CS_AS NOT NULL,
NombreCampoSQL varchar(128) COLLATE Modern_Spanish_CS_AS NOT NULL,
TipoDatoSQL varchar(128) COLLATE Modern_Spanish_CS_AS NOT NULL,
Valor nvarchar(250) COLLATE Modern_Spanish_CS_AS NOT NULL,
VisibleDesarrollador bit NOT NULL,
DescripcionRelacion nvarchar(500) COLLATE Modern_Spanish_CS_AS NULL
);
INSERT INTO @RelacionesResueltas
(
Orden,
CveTipoRelacion,
CveTabla,
CveCampo,
NombreTablaSQL,
NombreCampoSQL,
TipoDatoSQL,
Valor,
VisibleDesarrollador,
DescripcionRelacion
)
SELECT
R.Orden,
R.CveTipoRelacion,
T.CveTabla,
C.CveCampo,
R.NombreTablaSQL,
R.NombreCampoSQL,
C.TipoDatoSQL,
R.Valor,
R.VisibleDesarrollador,
R.DescripcionRelacion
FROM @Relaciones AS R
INNER JOIN dbo.Bit_Tablas AS T
ON T.NombreTablaSQL = R.NombreTablaSQL
AND T.Activo = 1
INNER JOIN dbo.Bit_Campos AS C
ON C.CveTabla = T.CveTabla
AND C.NombreCampoSQL = R.NombreCampoSQL
AND C.Activo = 1
INNER JOIN dbo.Bit_TiposRelacion AS TR
ON TR.CveTipoRelacion = R.CveTipoRelacion
AND TR.Activo = 1
WHERE C.TipoDatoSQL IS NOT NULL;
IF (SELECT COUNT(1) FROM @Relaciones) <>
(SELECT COUNT(1) FROM @RelacionesResueltas)
BEGIN
SET @ErrorMostrar = 'Una relación utiliza una tabla, campo o tipo que no está configurado en la bitácora.';
SET @ErrorTipo = 2;
RETURN;
END;
IF EXISTS
(
SELECT 1
FROM @RelacionesResueltas
WHERE TipoDatoSQL IN ('tinyint', 'smallint', 'int', 'bigint')
AND TRY_CONVERT(bigint, Valor) IS NULL
)
BEGIN
SET @ErrorMostrar = 'El valor de una relación numérica no es válido.';
SET @ErrorTipo = 2;
RETURN;
END;
IF EXISTS
(
SELECT 1
FROM @RelacionesResueltas
WHERE VisibleDesarrollador = 1
)
AND NOT EXISTS
(
SELECT 1
FROM @RelacionesResueltas
WHERE NombreTablaSQL = 'Clientes'
AND NombreCampoSQL = 'CveCliente'
AND VisibleDesarrollador = 1
)
BEGIN
SET @ErrorMostrar = 'Una bitácora visible para desarrolladores debe relacionarse con un cliente.';
SET @ErrorTipo = 2;
RETURN;
END;
DECLARE @Campos TABLE
(
Orden int NOT NULL,
NombreCampoSQL varchar(128) COLLATE Modern_Spanish_CS_AS NOT NULL,
ValorAnteriorEsNulo bit NOT NULL,
ValorAnterior nvarchar(max) COLLATE Modern_Spanish_CS_AS NULL,
ValorNuevoEsNulo bit NOT NULL,
ValorNuevo nvarchar(max) COLLATE Modern_Spanish_CS_AS NULL
);
IF @CamposXml IS NOT NULL
BEGIN
INSERT INTO @Campos
(
Orden,
NombreCampoSQL,
ValorAnteriorEsNulo,
ValorAnterior,
ValorNuevoEsNulo,
ValorNuevo
)
SELECT
C.value('@Orden', 'int'),
C.value('@NombreCampoSQL', 'varchar(128)'),
C.value('@ValorAnteriorEsNulo', 'bit'),
CASE
WHEN C.value('@ValorAnteriorEsNulo', 'bit') = 1 THEN NULL
ELSE C.value('@ValorAnterior', 'nvarchar(max)')
END,
C.value('@ValorNuevoEsNulo', 'bit'),
CASE
WHEN C.value('@ValorNuevoEsNulo', 'bit') = 1 THEN NULL
ELSE C.value('@ValorNuevo', 'nvarchar(max)')
END
FROM @CamposXml.nodes('/Campos/Campo') AS X(C);
END;
IF @CveTipoMovimiento IN (1, 2)
AND NOT EXISTS (SELECT 1 FROM @Campos)
BEGIN
SET @ErrorMostrar = 'Las altas y modificaciones deben incluir los campos auditados.';
SET @ErrorTipo = 2;
RETURN;
END;
IF EXISTS
(
SELECT 1
FROM @Campos AS F
LEFT JOIN dbo.Bit_Campos AS C
ON C.CveTabla = @CveTabla
AND C.NombreCampoSQL = F.NombreCampoSQL
AND C.Activo = 1
WHERE C.CveCampo IS NULL
)
BEGIN
SET @ErrorMostrar = 'Uno de los campos enviados no está configurado para la tabla auditada.';
SET @ErrorTipo = 2;
RETURN;
END;
INSERT INTO dbo.Bit_Bitacora
(
CveTabla,
CveTipoMovimiento,
CveDefinicionAccion,
CveUsuarioEjecuta,
CveUsuarioAutoriza,
FechaAutorizacion,
LlaveRegistro,
DescripcionMovimiento,
DireccionIP,
NombreEquipo,
Modulo
)
VALUES
(
@CveTabla,
@CveTipoMovimiento,
@CveDefinicionAccion,
@CveUsuarioEjecuta,
@CveUsuarioAutoriza,
@FechaAutorizacion,
@LlaveRegistro,
@DescripcionMovimiento,
@DireccionIP,
@NombreEquipo,
@Modulo
);
DECLARE @CveBitacora bigint = CONVERT(bigint, SCOPE_IDENTITY());
INSERT INTO dbo.Bit_BitacoraRelaciones
(
CveBitacora,
CveTipoRelacion,
CveTablaRelacionada,
LlaveRegistroRelacionada,
CveCampoRelacion,
ValorRelacionNumero,
ValorRelacionTexto,
DescripcionRelacion,
VisibleDesarrollador
)
SELECT
@CveBitacora,
R.CveTipoRelacion,
R.CveTabla,
R.Valor,
R.CveCampo,
CASE
WHEN R.TipoDatoSQL IN ('tinyint', 'smallint', 'int', 'bigint')
THEN TRY_CONVERT(bigint, R.Valor)
ELSE NULL
END,
CASE
WHEN R.TipoDatoSQL IN ('tinyint', 'smallint', 'int', 'bigint')
THEN NULL
ELSE R.Valor
END,
R.DescripcionRelacion,
R.VisibleDesarrollador
FROM @RelacionesResueltas AS R;
INSERT INTO dbo.Bit_BitacoraCampos
(
CveBitacora,
CveCampo,
ValorAnterior,
ValorNuevo
)
SELECT
@CveBitacora,
C.CveCampo,
F.ValorAnterior,
F.ValorNuevo
FROM @Campos AS F
INNER JOIN dbo.Bit_Campos AS C
ON C.CveTabla = @CveTabla
AND C.NombreCampoSQL = F.NombreCampoSQL
AND C.Activo = 1
WHERE @DiscriminarCamposSinCambios = 0
OR F.ValorAnteriorEsNulo <> F.ValorNuevoEsNulo
OR
(
F.ValorAnteriorEsNulo = 0
AND F.ValorNuevoEsNulo = 0
AND F.ValorAnterior <> F.ValorNuevo
);
SELECT @CveBitacora AS CveBitacora;
SET @Return = 1;
END TRY
BEGIN CATCH
SET @ErrorMostrar = 'Ocurrió un error al registrar la bitácora; favor de contactar a Sistemas.';
SET @ErrorTipo = 1;
SET @Return = 0;
DECLARE @ErrorTecnico nvarchar(2048) = CONCAT(
'Número: ', ERROR_NUMBER(),
'; Procedimiento: ', COALESCE(ERROR_PROCEDURE(), 'PA_Bit_BitacoraAdd'),
'; Línea: ', ERROR_LINE(),
'; Detalle: ', ERROR_MESSAGE()
);
RAISERROR(N'%s', 10, 1, @ErrorTecnico);
END CATCH;
END;
GO
CREATE OR ALTER PROCEDURE dbo.PA_Bit_BitacoraList
@NombreTablaSQL varchar(128) = NULL,
@LlaveRegistro nvarchar(250) = NULL,
@CveUsuarioFiltro int = NULL,
@FechaInicio datetime = NULL,
@FechaFin datetime = NULL,
@Modulo varchar(150) = NULL,
@CveUsuarioEjecuta int,
@ErrorMostrar varchar(max) OUTPUT,
@ErrorTipo int OUTPUT,
@Return bit OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SELECT
@ErrorMostrar = NULL,
@ErrorTipo = 0,
@Return = 0;
BEGIN TRY
DECLARE @EsAdministrador bit = 0;
DECLARE @EsDesarrollador bit = 0;
SELECT
@EsAdministrador = CASE
WHEN R.NombreRol IN ('SuperUsuario', 'Administrador') THEN 1
ELSE 0
END,
@EsDesarrollador = CASE
WHEN R.NombreRol = 'Empresa' THEN 1
ELSE 0
END
FROM dbo.Sis_Usuarios AS U
INNER JOIN dbo.Sis_Roles AS R
ON R.CveRol = U.CveRol
WHERE U.CveUsuario = @CveUsuarioEjecuta
AND U.Activo = 1
AND R.Activo = 1;
SELECT
B.CveBitacora,
B.CveTabla,
T.NombreTablaSQL,
T.NombreMostrar AS NombreTabla,
B.CveTipoMovimiento,
M.Nombre AS TipoMovimiento,
A.NombreAccion,
B.CveUsuarioEjecuta,
B.CveUsuarioAutoriza,
B.FechaAutorizacion,
B.LlaveRegistro,
B.DescripcionMovimiento,
B.FechaMovimiento,
B.DireccionIP,
B.NombreEquipo,
B.Modulo
FROM dbo.Bit_Bitacora AS B
INNER JOIN dbo.Bit_Tablas AS T
ON T.CveTabla = B.CveTabla
INNER JOIN dbo.Bit_TiposMovimiento AS M
ON M.CveTipoMovimiento = B.CveTipoMovimiento
LEFT JOIN dbo.Bit_DefinicionesAccion AS A
ON A.CveDefinicionAccion = B.CveDefinicionAccion
WHERE (@NombreTablaSQL IS NULL OR T.NombreTablaSQL = @NombreTablaSQL COLLATE Modern_Spanish_CS_AS)
AND (@LlaveRegistro IS NULL OR B.LlaveRegistro = @LlaveRegistro COLLATE Modern_Spanish_CS_AS)
AND (@CveUsuarioFiltro IS NULL OR B.CveUsuarioEjecuta = @CveUsuarioFiltro)
AND (@FechaInicio IS NULL OR B.FechaMovimiento >= @FechaInicio)
AND
(
@FechaFin IS NULL
OR B.FechaMovimiento < DATEADD(day, 1, CONVERT(date, @FechaFin))
)
AND (@Modulo IS NULL OR B.Modulo = @Modulo COLLATE Modern_Spanish_CS_AS)
AND
(
@EsAdministrador = 1
OR
(
@EsDesarrollador = 1
AND EXISTS
(
SELECT 1
FROM dbo.Bit_BitacoraRelaciones AS BR
INNER JOIN dbo.Bit_Tablas AS RT
ON RT.CveTabla = BR.CveTablaRelacionada
INNER JOIN dbo.Bit_Campos AS RC
ON RC.CveCampo = BR.CveCampoRelacion
AND RC.CveTabla = RT.CveTabla
INNER JOIN dbo.Sis_UsuariosClientes AS UC
ON UC.CveCliente = BR.ValorRelacionNumero
AND UC.CveUsuario = @CveUsuarioEjecuta
AND UC.Activo = 1
WHERE BR.CveBitacora = B.CveBitacora
AND BR.VisibleDesarrollador = 1
AND RT.NombreTablaSQL = 'Clientes'
AND RC.NombreCampoSQL = 'CveCliente'
)
)
)
ORDER BY
B.FechaMovimiento DESC,
B.CveBitacora DESC;
SET @Return = 1;
END TRY
BEGIN CATCH
SET @ErrorMostrar = 'Ocurrió un error al consultar la bitácora; favor de contactar a Sistemas.';
SET @ErrorTipo = 1;
SET @Return = 0;
DECLARE @ErrorTecnico nvarchar(2048) = CONCAT(
'Número: ', ERROR_NUMBER(),
'; Procedimiento: ', COALESCE(ERROR_PROCEDURE(), 'PA_Bit_BitacoraList'),
'; Línea: ', ERROR_LINE(),
'; Detalle: ', ERROR_MESSAGE()
);
RAISERROR(N'%s', 10, 1, @ErrorTecnico);
END CATCH;
END;
GO
SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO
CREATE OR ALTER PROCEDURE dbo.PA_Bit_BitacoraListByRelations
@RelacionesXml xml = NULL,
@RelacionesMostrarXml xml = NULL,
@RegistrosOmitidos int,
@RegistrosPorPagina int,
@CveUsuarioEjecuta int,
@ErrorMostrar varchar(max) OUTPUT,
@ErrorTipo int OUTPUT,
@Return bit OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SELECT
@ErrorMostrar = NULL,
@ErrorTipo = 0,
@Return = 0;
BEGIN TRY
IF @RegistrosOmitidos < 0 OR @RegistrosPorPagina <= 0
BEGIN
SET @ErrorMostrar = 'Los datos de paginación no son válidos.';
SET @ErrorTipo = 2;
RETURN;
END;
DECLARE @EsAdministrador bit = 0;
DECLARE @EsDesarrollador bit = 0;
SELECT
@EsAdministrador = CASE
WHEN R.NombreRol IN ('SuperUsuario', 'Administrador') THEN 1
ELSE 0
END,
@EsDesarrollador = CASE
WHEN R.NombreRol = 'Empresa' THEN 1
ELSE 0
END
FROM dbo.Sis_Usuarios AS U
INNER JOIN dbo.Sis_Roles AS R
ON R.CveRol = U.CveRol
WHERE U.CveUsuario = @CveUsuarioEjecuta
AND U.Activo = 1
AND R.Activo = 1;
DECLARE @Filtros TABLE
(
Orden int NOT NULL PRIMARY KEY,
NombreTablaSQL varchar(128)
COLLATE Modern_Spanish_CS_AS NOT NULL,
NombreCampoSQL varchar(128)
COLLATE Modern_Spanish_CS_AS NOT NULL,
Valor nvarchar(250)
COLLATE Modern_Spanish_CS_AS NOT NULL,
SoloExistencia bit NOT NULL
);
IF @RelacionesXml IS NOT NULL
BEGIN
INSERT INTO @Filtros
(
Orden,
NombreTablaSQL,
NombreCampoSQL,
Valor,
SoloExistencia
)
SELECT
R.value('@Orden', 'int'),
R.value('@Tabla', 'varchar(128)'),
R.value('@Campo', 'varchar(128)'),
R.value('@Valor', 'nvarchar(250)'),
CASE
WHEN R.exist('@SoloExistencia') = 1
THEN R.value('@SoloExistencia', 'bit')
ELSE 0
END
FROM @RelacionesXml.nodes('/Relaciones/Relacion') AS X(R);
END;
DECLARE @FiltrosResueltos TABLE
(
Orden int NOT NULL PRIMARY KEY,
CveTabla int NOT NULL,
CveCampo int NOT NULL,
TipoDatoSQL varchar(128)
COLLATE Modern_Spanish_CS_AS NOT NULL,
Valor nvarchar(250)
COLLATE Modern_Spanish_CS_AS NOT NULL,
SoloExistencia bit NOT NULL,
EsEntero bit NOT NULL
);
INSERT INTO @FiltrosResueltos
(
Orden,
CveTabla,
CveCampo,
TipoDatoSQL,
Valor,
SoloExistencia,
EsEntero
)
SELECT
F.Orden,
T.CveTabla,
C.CveCampo,
C.TipoDatoSQL,
F.Valor,
F.SoloExistencia,
CASE
WHEN C.TipoDatoSQL IN
(
'tinyint',
'smallint',
'int',
'bigint'
) THEN 1
ELSE 0
END
FROM @Filtros AS F
INNER JOIN dbo.Bit_Tablas AS T
ON T.NombreTablaSQL = F.NombreTablaSQL
AND T.Activo = 1
INNER JOIN dbo.Bit_Campos AS C
ON C.CveTabla = T.CveTabla
AND C.NombreCampoSQL = F.NombreCampoSQL
AND C.Activo = 1
INNER JOIN sys.schemas AS SF
ON SF.name = 'dbo'
INNER JOIN sys.tables AS TF
ON TF.schema_id = SF.schema_id
AND TF.name COLLATE Modern_Spanish_CS_AS = T.NombreTablaSQL
INNER JOIN sys.columns AS CF
ON CF.object_id = TF.object_id
AND CF.name COLLATE Modern_Spanish_CS_AS = C.NombreCampoSQL
WHERE C.TipoDatoSQL IS NOT NULL;
IF (SELECT COUNT(1) FROM @Filtros) <>
(SELECT COUNT(1) FROM @FiltrosResueltos)
BEGIN
SET @ErrorMostrar = 'Una relación utiliza una tabla o campo que no está configurado en la bitácora.';
SET @ErrorTipo = 2;
RETURN;
END;
IF EXISTS
(
SELECT 1
FROM @FiltrosResueltos
WHERE SoloExistencia = 0
AND EsEntero = 1
AND TRY_CONVERT(bigint, Valor) IS NULL
)
BEGIN
SET @ErrorMostrar = 'El valor de una relación numérica no es válido.';
SET @ErrorTipo = 2;
RETURN;
END;
DECLARE @RelacionesMostrar TABLE
(
Orden int NOT NULL,
NombreTablaSQL varchar(128)
COLLATE Modern_Spanish_CS_AS NOT NULL,
NombreCampoSQL varchar(128)
COLLATE Modern_Spanish_CS_AS NOT NULL
);
IF @RelacionesMostrarXml IS NOT NULL
BEGIN
INSERT INTO @RelacionesMostrar
(
Orden,
NombreTablaSQL,
NombreCampoSQL
)
SELECT
R.value('@Orden', 'int'),
R.value('@Tabla', 'varchar(128)'),
R.value('@Campo', 'varchar(128)')
FROM @RelacionesMostrarXml.nodes('/RelacionesMostrar/Relacion') AS X(R);
END;
IF (SELECT COUNT(1) FROM @RelacionesMostrar) > 10
OR EXISTS
(
SELECT 1
FROM @RelacionesMostrar
WHERE Orden <= 0
)
OR EXISTS
(
SELECT Orden
FROM @RelacionesMostrar
GROUP BY Orden
HAVING COUNT(1) > 1
)
OR EXISTS
(
SELECT
NombreTablaSQL,
NombreCampoSQL
FROM @RelacionesMostrar
GROUP BY
NombreTablaSQL,
NombreCampoSQL
HAVING COUNT(1) > 1
)
BEGIN
SET @ErrorMostrar = 'La configuración de relaciones a mostrar no es válida.';
SET @ErrorTipo = 2;
RETURN;
END;
DECLARE @RelacionesMostrarResueltas TABLE
(
Orden int NOT NULL PRIMARY KEY,
CveTabla int NOT NULL,
NombreTablaSQL varchar(128)
COLLATE Modern_Spanish_CS_AS NOT NULL,
NombreTabla varchar(150)
COLLATE Modern_Spanish_CS_AS NOT NULL,
CveCampoLlave int NOT NULL,
NombreCampoLlaveSQL varchar(128)
COLLATE Modern_Spanish_CS_AS NOT NULL,
CveCampoMostrar int NOT NULL,
NombreCampoSQL varchar(128)
COLLATE Modern_Spanish_CS_AS NOT NULL,
NombreCampo varchar(150)
COLLATE Modern_Spanish_CS_AS NOT NULL
);
INSERT INTO @RelacionesMostrarResueltas
(
Orden,
CveTabla,
NombreTablaSQL,
NombreTabla,
CveCampoLlave,
NombreCampoLlaveSQL,
CveCampoMostrar,
NombreCampoSQL,
NombreCampo
)
SELECT
R.Orden,
T.CveTabla,
T.NombreTablaSQL,
T.NombreMostrar,
CL.CveCampo,
CL.NombreCampoSQL,
CM.CveCampo,
CM.NombreCampoSQL,
CM.NombreMostrar
FROM @RelacionesMostrar AS R
INNER JOIN dbo.Bit_Tablas AS T
ON T.NombreTablaSQL = R.NombreTablaSQL
AND T.Activo = 1
AND T.NombreCampoLlaveSQL IS NOT NULL
INNER JOIN dbo.Bit_Campos AS CL
ON CL.CveTabla = T.CveTabla
AND CL.NombreCampoSQL = T.NombreCampoLlaveSQL
AND CL.Activo = 1
INNER JOIN dbo.Bit_Campos AS CM
ON CM.CveTabla = T.CveTabla
AND CM.NombreCampoSQL = R.NombreCampoSQL
AND CM.MostrarEnBitacora = 1
AND CM.Activo = 1
INNER JOIN sys.schemas AS SC
ON SC.name = 'dbo'
INNER JOIN sys.tables AS ST
ON ST.schema_id = SC.schema_id
AND ST.name COLLATE Modern_Spanish_CS_AS = T.NombreTablaSQL
INNER JOIN sys.columns AS SCL
ON SCL.object_id = ST.object_id
AND SCL.name COLLATE Modern_Spanish_CS_AS = CL.NombreCampoSQL
INNER JOIN sys.columns AS SCM
ON SCM.object_id = ST.object_id
AND SCM.name COLLATE Modern_Spanish_CS_AS = CM.NombreCampoSQL;
IF (SELECT COUNT(1) FROM @RelacionesMostrar) <>
(SELECT COUNT(1) FROM @RelacionesMostrarResueltas)
BEGIN
SET @ErrorMostrar = 'Una relación a mostrar utiliza una tabla o campo no permitido.';
SET @ErrorTipo = 2;
RETURN;
END;
CREATE TABLE #BitacorasCoincidentes
(
CveBitacora bigint NOT NULL PRIMARY KEY,
FechaMovimiento datetime NOT NULL
);
INSERT INTO #BitacorasCoincidentes
(
CveBitacora,
FechaMovimiento
)
SELECT
B.CveBitacora,
B.FechaMovimiento
FROM dbo.Bit_Bitacora AS B
WHERE
(
@EsAdministrador = 1
OR
(
@EsDesarrollador = 1
AND EXISTS
(
SELECT 1
FROM dbo.Bit_BitacoraRelaciones AS BRCliente
INNER JOIN dbo.Bit_Tablas AS TCliente
ON TCliente.CveTabla =
BRCliente.CveTablaRelacionada
INNER JOIN dbo.Bit_Campos AS CCliente
ON CCliente.CveCampo =
BRCliente.CveCampoRelacion
AND CCliente.CveTabla = TCliente.CveTabla
INNER JOIN dbo.Sis_UsuariosClientes AS UC
ON UC.CveCliente =
BRCliente.ValorRelacionNumero
AND UC.CveUsuario = @CveUsuarioEjecuta
AND UC.Activo = 1
WHERE BRCliente.CveBitacora = B.CveBitacora
AND BRCliente.VisibleDesarrollador = 1
AND TCliente.NombreTablaSQL = 'Clientes'
AND CCliente.NombreCampoSQL = 'CveCliente'
)
)
)
AND
(
@EsDesarrollador = 0
OR NOT EXISTS
(
SELECT 1
FROM @FiltrosResueltos AS FCliente
INNER JOIN dbo.Bit_Tablas AS TClienteFiltro
ON TClienteFiltro.CveTabla = FCliente.CveTabla
INNER JOIN dbo.Bit_Campos AS CClienteFiltro
ON CClienteFiltro.CveCampo = FCliente.CveCampo
AND CClienteFiltro.CveTabla =
TClienteFiltro.CveTabla
WHERE TClienteFiltro.NombreTablaSQL = 'Clientes'
AND CClienteFiltro.NombreCampoSQL = 'CveCliente'
AND FCliente.SoloExistencia = 0
AND NOT EXISTS
(
SELECT 1
FROM dbo.Sis_UsuariosClientes AS UCClienteFiltro
WHERE UCClienteFiltro.CveUsuario =
@CveUsuarioEjecuta
AND UCClienteFiltro.CveCliente =
TRY_CONVERT(bigint, FCliente.Valor)
AND UCClienteFiltro.Activo = 1
)
)
)
AND NOT EXISTS
(
SELECT 1
FROM @FiltrosResueltos AS F
WHERE NOT EXISTS
(
SELECT 1
FROM dbo.Bit_BitacoraRelaciones AS BR
WHERE BR.CveBitacora = B.CveBitacora
AND BR.CveTablaRelacionada = F.CveTabla
AND BR.CveCampoRelacion = F.CveCampo
AND
(
@EsAdministrador = 1
OR BR.VisibleDesarrollador = 1
)
AND
(
F.SoloExistencia = 1
OR
(
(
F.EsEntero = 1
AND BR.ValorRelacionNumero =
TRY_CONVERT(bigint, F.Valor)
)
OR
(
F.EsEntero = 0
AND BR.ValorRelacionTexto =
F.Valor COLLATE Modern_Spanish_CS_AS
)
)
)
)
);
DECLARE @TotalRegistros int;
SELECT @TotalRegistros = COUNT(DISTINCT CveBitacora)
FROM #BitacorasCoincidentes;
CREATE TABLE #BitacorasPagina
(
CveBitacora bigint NOT NULL PRIMARY KEY,
Orden int NOT NULL
);
INSERT INTO #BitacorasPagina
(
CveBitacora,
Orden
)
SELECT
C.CveBitacora,
ROW_NUMBER() OVER
(
ORDER BY
C.FechaMovimiento DESC,
C.CveBitacora DESC
)
FROM #BitacorasCoincidentes AS C
ORDER BY
C.FechaMovimiento DESC,
C.CveBitacora DESC
OFFSET @RegistrosOmitidos ROWS
FETCH NEXT @RegistrosPorPagina ROWS ONLY;
SELECT @TotalRegistros AS TotalRegistros;
SELECT
B.CveBitacora,
B.CveTabla,
T.NombreTablaSQL,
T.NombreMostrar AS NombreTabla,
B.CveTipoMovimiento,
M.Nombre AS TipoMovimiento,
B.CveDefinicionAccion,
A.NombreAccion,
A.DescripcionAccion,
B.CveUsuarioEjecuta,
COALESCE(
NULLIF(U.NombreUsuario, ''),
CONCAT('(', B.CveUsuarioEjecuta, ') Eliminado')
) AS NombreUsuarioEjecuta,
B.CveUsuarioAutoriza,
B.FechaAutorizacion,
B.LlaveRegistro,
B.DescripcionMovimiento,
B.FechaMovimiento,
B.DireccionIP,
B.NombreEquipo,
B.Modulo
FROM #BitacorasPagina AS P
INNER JOIN dbo.Bit_Bitacora AS B
ON B.CveBitacora = P.CveBitacora
INNER JOIN dbo.Bit_Tablas AS T
ON T.CveTabla = B.CveTabla
INNER JOIN dbo.Bit_TiposMovimiento AS M
ON M.CveTipoMovimiento = B.CveTipoMovimiento
LEFT JOIN dbo.Bit_DefinicionesAccion AS A
ON A.CveDefinicionAccion = B.CveDefinicionAccion
LEFT JOIN dbo.Sis_Usuarios AS U
ON U.CveUsuario = B.CveUsuarioEjecuta
ORDER BY P.Orden;
CREATE TABLE #CamposPagina
(
OrdenPagina int NOT NULL,
CveBitacoraCampo bigint NOT NULL PRIMARY KEY,
CveBitacora bigint NOT NULL,
CveCampo int NOT NULL,
NombreCampoSQL varchar(128)
COLLATE Modern_Spanish_CS_AS NOT NULL,
NombreMostrar varchar(150)
COLLATE Modern_Spanish_CS_AS NOT NULL,
ValorAnterior nvarchar(max)
COLLATE Modern_Spanish_CS_AS NULL,
ValorNuevo nvarchar(max)
COLLATE Modern_Spanish_CS_AS NULL,
ValorAnteriorMostrar nvarchar(max)
COLLATE Modern_Spanish_CS_AS NULL,
ValorNuevoMostrar nvarchar(max)
COLLATE Modern_Spanish_CS_AS NULL
);
INSERT INTO #CamposPagina
(
OrdenPagina,
CveBitacoraCampo,
CveBitacora,
CveCampo,
NombreCampoSQL,
NombreMostrar,
ValorAnterior,
ValorNuevo,
ValorAnteriorMostrar,
ValorNuevoMostrar
)
SELECT
P.Orden,
BC.CveBitacoraCampo,
BC.CveBitacora,
BC.CveCampo,
C.NombreCampoSQL,
C.NombreMostrar,
BC.ValorAnterior,
BC.ValorNuevo,
BC.ValorAnterior,
BC.ValorNuevo
FROM #BitacorasPagina AS P
INNER JOIN dbo.Bit_BitacoraCampos AS BC
ON BC.CveBitacora = P.CveBitacora
INNER JOIN dbo.Bit_Campos AS C
ON C.CveCampo = BC.CveCampo
WHERE @EsAdministrador = 1
OR C.MostrarEnBitacora = 1;
DECLARE @CveCampoOrigenReferencia int;
DECLARE @NombreTablaReferencia varchar(128);
DECLARE @NombreCampoLlaveReferencia varchar(128);
DECLARE @NombreCampoMostrarReferencia varchar(128);
DECLARE @SqlCampoReferencia nvarchar(max);
-- Los identificadores del SQL dinámico salen únicamente de metadatos
-- activos y se verifican contra sys.tables/sys.columns antes de usarse.
DECLARE CursorCamposReferencia CURSOR LOCAL FAST_FORWARD FOR
SELECT DISTINCT
CO.CveCampo,
TR.NombreTablaSQL,
CL.NombreCampoSQL,
CM.NombreCampoSQL
FROM #CamposPagina AS CP
INNER JOIN dbo.Bit_Campos AS CO
ON CO.CveCampo = CP.CveCampo
AND CO.Activo = 1
INNER JOIN dbo.Bit_Tablas AS TR
ON TR.CveTabla = CO.CveTablaReferencia
AND TR.Activo = 1
AND TR.NombreCampoLlaveSQL IS NOT NULL
INNER JOIN dbo.Bit_Campos AS CL
ON CL.CveTabla = TR.CveTabla
AND CL.NombreCampoSQL = TR.NombreCampoLlaveSQL
AND CL.Activo = 1
INNER JOIN dbo.Bit_Campos AS CM
ON CM.CveCampo = CO.CveCampoMostrarReferencia
AND CM.CveTabla = TR.CveTabla
AND CM.MostrarEnBitacora = 1
AND CM.Activo = 1
INNER JOIN sys.schemas AS SC
ON SC.name = 'dbo'
INNER JOIN sys.tables AS ST
ON ST.schema_id = SC.schema_id
AND ST.name COLLATE Modern_Spanish_CS_AS = TR.NombreTablaSQL
INNER JOIN sys.columns AS SCL
ON SCL.object_id = ST.object_id
AND SCL.name COLLATE Modern_Spanish_CS_AS = CL.NombreCampoSQL
INNER JOIN sys.columns AS SCM
ON SCM.object_id = ST.object_id
AND SCM.name COLLATE Modern_Spanish_CS_AS = CM.NombreCampoSQL;
OPEN CursorCamposReferencia;
FETCH NEXT FROM CursorCamposReferencia INTO
@CveCampoOrigenReferencia,
@NombreTablaReferencia,
@NombreCampoLlaveReferencia,
@NombreCampoMostrarReferencia;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @SqlCampoReferencia = N'
UPDATE CP
SET
CP.ValorAnteriorMostrar = CASE
WHEN CP.ValorAnterior IS NULL THEN NULL
WHEN VA.' + QUOTENAME(@NombreCampoLlaveReferencia) + N' IS NULL
THEN CONCAT(N''('', CP.ValorAnterior, N'') Eliminada'')
WHEN NULLIF(CONVERT(nvarchar(max), VA.' + QUOTENAME(@NombreCampoMostrarReferencia) + N'), N'''') IS NULL
THEN CONCAT(N''('', CP.ValorAnterior, N'')'')
ELSE CONVERT(nvarchar(max), VA.' + QUOTENAME(@NombreCampoMostrarReferencia) + N')
END,
CP.ValorNuevoMostrar = CASE
WHEN CP.ValorNuevo IS NULL THEN NULL
WHEN VN.' + QUOTENAME(@NombreCampoLlaveReferencia) + N' IS NULL
THEN CONCAT(N''('', CP.ValorNuevo, N'') Eliminada'')
WHEN NULLIF(CONVERT(nvarchar(max), VN.' + QUOTENAME(@NombreCampoMostrarReferencia) + N'), N'''') IS NULL
THEN CONCAT(N''('', CP.ValorNuevo, N'')'')
ELSE CONVERT(nvarchar(max), VN.' + QUOTENAME(@NombreCampoMostrarReferencia) + N')
END
FROM #CamposPagina AS CP
LEFT JOIN dbo.' + QUOTENAME(@NombreTablaReferencia) + N' AS VA
ON CONVERT(nvarchar(250), VA.' + QUOTENAME(@NombreCampoLlaveReferencia) + N')
COLLATE Modern_Spanish_CS_AS =
CP.ValorAnterior COLLATE Modern_Spanish_CS_AS
LEFT JOIN dbo.' + QUOTENAME(@NombreTablaReferencia) + N' AS VN
ON CONVERT(nvarchar(250), VN.' + QUOTENAME(@NombreCampoLlaveReferencia) + N')
COLLATE Modern_Spanish_CS_AS =
CP.ValorNuevo COLLATE Modern_Spanish_CS_AS
WHERE CP.CveCampo = @CveCampoOrigen;';
EXEC sys.sp_executesql
@SqlCampoReferencia,
N'@CveCampoOrigen int',
@CveCampoOrigen = @CveCampoOrigenReferencia;
FETCH NEXT FROM CursorCamposReferencia INTO
@CveCampoOrigenReferencia,
@NombreTablaReferencia,
@NombreCampoLlaveReferencia,
@NombreCampoMostrarReferencia;
END;
CLOSE CursorCamposReferencia;
DEALLOCATE CursorCamposReferencia;
SELECT
CveBitacoraCampo,
CveBitacora,
CveCampo,
NombreCampoSQL,
NombreMostrar,
ValorAnterior,
ValorNuevo,
ValorAnteriorMostrar,
ValorNuevoMostrar
FROM #CamposPagina
ORDER BY
OrdenPagina,
CveBitacoraCampo;
SELECT
BR.CveBitacoraRelacion,
BR.CveBitacora,
BR.CveTipoRelacion,
TR.Nombre AS TipoRelacion,
BR.CveTablaRelacionada,
T.NombreTablaSQL,
BR.CveCampoRelacion,
C.NombreCampoSQL,
BR.LlaveRegistroRelacionada,
BR.ValorRelacionNumero,
BR.ValorRelacionTexto,
BR.VisibleDesarrollador,
BR.DescripcionRelacion
FROM #BitacorasPagina AS P
INNER JOIN dbo.Bit_BitacoraRelaciones AS BR
ON BR.CveBitacora = P.CveBitacora
INNER JOIN dbo.Bit_TiposRelacion AS TR
ON TR.CveTipoRelacion = BR.CveTipoRelacion
INNER JOIN dbo.Bit_Tablas AS T
ON T.CveTabla = BR.CveTablaRelacionada
LEFT JOIN dbo.Bit_Campos AS C
ON C.CveCampo = BR.CveCampoRelacion
AND C.CveTabla = T.CveTabla
WHERE @EsAdministrador = 1
OR BR.VisibleDesarrollador = 1
ORDER BY
P.Orden,
BR.CveBitacoraRelacion;
CREATE TABLE #RelacionesVisuales
(
CveBitacora bigint NOT NULL,
Orden int NOT NULL,
NombreTablaSQL varchar(128)
COLLATE Modern_Spanish_CS_AS NOT NULL,
NombreTabla varchar(150)
COLLATE Modern_Spanish_CS_AS NOT NULL,
NombreCampoSQL varchar(128)
COLLATE Modern_Spanish_CS_AS NOT NULL,
NombreCampo varchar(150)
COLLATE Modern_Spanish_CS_AS NOT NULL,
ValorClave nvarchar(250)
COLLATE Modern_Spanish_CS_AS NOT NULL,
ValorMostrar nvarchar(max)
COLLATE Modern_Spanish_CS_AS NOT NULL
);
DECLARE @OrdenRelacionMostrar int;
DECLARE @CveTablaRelacionMostrar int;
DECLARE @NombreTablaSQLRelacionMostrar varchar(128);
DECLARE @NombreTablaRelacionMostrar varchar(150);
DECLARE @CveCampoLlaveRelacionMostrar int;
DECLARE @NombreCampoLlaveRelacionMostrar varchar(128);
DECLARE @NombreCampoSQLRelacionMostrar varchar(128);
DECLARE @NombreCampoRelacionMostrar varchar(150);
DECLARE @SqlRelacionMostrar nvarchar(max);
-- Tabla, llave y campo visible ya fueron resueltos contra la allowlist
-- de Bit_Tablas/Bit_Campos y se delimitan nuevamente con QUOTENAME.
DECLARE CursorRelacionesMostrar CURSOR LOCAL FAST_FORWARD FOR
SELECT
Orden,
CveTabla,
NombreTablaSQL,
NombreTabla,
CveCampoLlave,
NombreCampoLlaveSQL,
NombreCampoSQL,
NombreCampo
FROM @RelacionesMostrarResueltas
ORDER BY Orden;
OPEN CursorRelacionesMostrar;
FETCH NEXT FROM CursorRelacionesMostrar INTO
@OrdenRelacionMostrar,
@CveTablaRelacionMostrar,
@NombreTablaSQLRelacionMostrar,
@NombreTablaRelacionMostrar,
@CveCampoLlaveRelacionMostrar,
@NombreCampoLlaveRelacionMostrar,
@NombreCampoSQLRelacionMostrar,
@NombreCampoRelacionMostrar;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @SqlRelacionMostrar = N'
INSERT INTO #RelacionesVisuales
(
CveBitacora,
Orden,
NombreTablaSQL,
NombreTabla,
NombreCampoSQL,
NombreCampo,
ValorClave,
ValorMostrar
)
SELECT
BR.CveBitacora,
@Orden,
@NombreTablaSQL,
@NombreTabla,
@NombreCampoSQL,
@NombreCampo,
BR.LlaveRegistroRelacionada,
CASE
WHEN V.' + QUOTENAME(@NombreCampoLlaveRelacionMostrar) + N' IS NULL
THEN CONCAT(N''('', BR.LlaveRegistroRelacionada, N'') Eliminada'')
WHEN NULLIF(CONVERT(nvarchar(max), V.' + QUOTENAME(@NombreCampoSQLRelacionMostrar) + N'), N'''') IS NULL
THEN CONCAT(N''('', BR.LlaveRegistroRelacionada, N'')'')
ELSE CONVERT(nvarchar(max), V.' + QUOTENAME(@NombreCampoSQLRelacionMostrar) + N')
END
FROM #BitacorasPagina AS P
INNER JOIN dbo.Bit_BitacoraRelaciones AS BR
ON BR.CveBitacora = P.CveBitacora
INNER JOIN dbo.Bit_Bitacora AS B
ON B.CveBitacora = P.CveBitacora
LEFT JOIN dbo.' + QUOTENAME(@NombreTablaSQLRelacionMostrar) + N' AS V
ON CONVERT(nvarchar(250), V.' + QUOTENAME(@NombreCampoLlaveRelacionMostrar) + N')
COLLATE Modern_Spanish_CS_AS =
BR.LlaveRegistroRelacionada COLLATE Modern_Spanish_CS_AS
WHERE BR.CveTablaRelacionada = @CveTabla
AND BR.CveCampoRelacion = @CveCampoLlave
AND NOT
(
BR.CveTipoRelacion = 1
AND BR.CveTablaRelacionada = B.CveTabla
)
AND
(
@EsAdministrador = 1
OR BR.VisibleDesarrollador = 1
);';
EXEC sys.sp_executesql
@SqlRelacionMostrar,
N'@Orden int,
@NombreTablaSQL varchar(128),
@NombreTabla varchar(150),
@NombreCampoSQL varchar(128),
@NombreCampo varchar(150),
@CveTabla int,
@CveCampoLlave int,
@EsAdministrador bit',
@Orden = @OrdenRelacionMostrar,
@NombreTablaSQL = @NombreTablaSQLRelacionMostrar,
@NombreTabla = @NombreTablaRelacionMostrar,
@NombreCampoSQL = @NombreCampoSQLRelacionMostrar,
@NombreCampo = @NombreCampoRelacionMostrar,
@CveTabla = @CveTablaRelacionMostrar,
@CveCampoLlave = @CveCampoLlaveRelacionMostrar,
@EsAdministrador = @EsAdministrador;
FETCH NEXT FROM CursorRelacionesMostrar INTO
@OrdenRelacionMostrar,
@CveTablaRelacionMostrar,
@NombreTablaSQLRelacionMostrar,
@NombreTablaRelacionMostrar,
@CveCampoLlaveRelacionMostrar,
@NombreCampoLlaveRelacionMostrar,
@NombreCampoSQLRelacionMostrar,
@NombreCampoRelacionMostrar;
END;
CLOSE CursorRelacionesMostrar;
DEALLOCATE CursorRelacionesMostrar;
SELECT
RV.CveBitacora,
RV.Orden,
RV.NombreTablaSQL,
RV.NombreTabla,
RV.NombreCampoSQL,
RV.NombreCampo,
RV.ValorClave,
RV.ValorMostrar
FROM #RelacionesVisuales AS RV
INNER JOIN #BitacorasPagina AS P
ON P.CveBitacora = RV.CveBitacora
ORDER BY
P.Orden,
RV.Orden;
SET @Return = 1;
END TRY
BEGIN CATCH
SET @ErrorMostrar = 'Ocurrió un error al consultar la bitácora; favor de contactar a Sistemas.';
SET @ErrorTipo = 1;
SET @Return = 0;
DECLARE @ErrorTecnico nvarchar(2048) = CONCAT(
'Número: ', ERROR_NUMBER(),
'; Procedimiento: ', COALESCE(
ERROR_PROCEDURE(),
'PA_Bit_BitacoraListByRelations'
),
'; Línea: ', ERROR_LINE(),
'; Detalle: ', ERROR_MESSAGE()
);
RAISERROR(N'%s', 10, 1, @ErrorTecnico);
END CATCH;
END;
GO