5.0 KiB
5.0 KiB
Reglas obligatorias de procedimientos almacenados
Estas reglas complementan AGENTS.md y son obligatorias para toda consulta nueva o modificada en la aplicación.
Acceso a datos
- Todas las lecturas y escrituras de la aplicación deben usar procedimientos almacenados.
- No escribir
SELECT,INSERT,UPDATE,DELETEniMERGEdirectamente en C# dentro de repositorios, servicios, páginas, controles o la master page. - Los repositorios deben usar
CommandType.StoredProcedure. - Todos los valores proporcionados por la aplicación deben enviarse como parámetros.
- Nunca concatenar entrada del usuario en SQL.
Nombres
- Usar el formato
PA_<Tipo>_<Entidad><Accion>. PAsignifica procedimiento almacenado.<Tipo>identifica el grupo funcional:Sis,Tra,Vta,Conta,Clientes,Fraccionamientos, etcétera.<Entidad>identifica el objeto y<Accion>describe claramente la operación; por ejemploAdd,Update,List,Activate,DeactivateoDelete.- Ejemplos:
PA_Sis_UsuarioAdd,PA_Sis_UsuarioUpdate,PA_Sis_UsuarioList,PA_Sis_UsuarioActivate,PA_Sis_UsuarioDeactivateyPA_Sis_UsuarioDelete.
Parámetros y resultado obligatorios
Todos los procedimientos deben declarar:
@CveUsuarioEjecuta int,
@ErrorMostrar varchar(max) OUTPUT,
@ErrorTipo int OUTPUT,
@Return bit OUTPUT
@CveUsuarioEjecutaidentifica al usuario autenticado que ejecuta la operación.- Al inicio, establecer
@ErrorMostrar = NULL,@ErrorTipo = 0y@Return = 0. - Establecer
@Return = 1únicamente cuando la operación termine correctamente. @ErrorTipo = 0: sin error ni advertencia.@ErrorTipo = 1: error.@ErrorTipo = 2: advertencia.@ErrorMostrarcontiene el mensaje amigable en español que puede mostrarse al usuario.- No devolver contraseñas, hashes, cadenas de conexión, SQL, stack traces ni detalles internos mediante
@ErrorMostrar. - Los procedimientos de consulta pueden devolver un result set, pero también deben poblar los parámetros comunes.
- El repositorio debe convertir los parámetros de salida en un modelo de resultado como
DbResult<T>.
Control de errores
- Usar
SET NOCOUNT ONyTRY/CATCHen todos los procedimientos. - Usar
SET XACT_ABORT ONcuando exista una mutación o transacción. - Iniciar la transacción dentro de
TRY, confirmar sólo después del éxito y ejecutar rollback enCATCHcuandoXACT_STATE() <> 0. - Una validación fallida debe establecer los parámetros de salida y ejecutar
RETURN; no debe continuar la mutación. - Para validar existencia, usar normalmente
EXISTSen lugar deCOUNT(*). - En
CATCH, generar un mensaje técnico separado conERROR_NUMBER(),ERROR_PROCEDURE(),ERROR_LINE()yERROR_MESSAGE()para el log. - El mensaje técnico puede notificarse con severidad informativa para que el ejecutor lo registre, pero nunca debe mostrarse directamente al usuario.
Borrado lógico
- Está prohibido usar
DELETEfísico en procedimientos CRUD normales. - Para borrar:
Borrado = 1yFechaBorrado = SYSDATETIME(). - Para restaurar:
Borrado = 0yFechaBorrado = NULL. - Las consultas normales deben filtrar
Borrado = 0en cada tabla participante, excepto cuando el caso de uso solicite expresamente registros borrados. - La eliminación permanente sólo puede realizarse mediante el procedimiento controlado de retención y limpieza.
- Ninguna página ASPX puede llamar directamente a la limpieza física.
Plantilla requerida
CREATE OR ALTER PROCEDURE [dbo].[PA_Sis_RolAdd]
@Rol varchar(50),
@CveUsuarioEjecuta int,
@ErrorMostrar varchar(max) OUTPUT,
@ErrorTipo int OUTPUT,
@Return bit OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
SELECT
@ErrorMostrar = NULL,
@ErrorTipo = 0,
@Return = 0;
BEGIN TRY
IF EXISTS
(
SELECT 1
FROM dbo.Sis_Roles
WHERE NombreRol = @Rol
AND Borrado = 0
)
BEGIN
SET @ErrorMostrar = CONCAT('El rol ''', @Rol, ''' ya se encuentra registrado.');
SET @ErrorTipo = 2;
RETURN;
END;
INSERT INTO dbo.Sis_Roles
(NombreRol, Activo, FechaCreacion)
VALUES
(@Rol, 1, SYSDATETIME());
SET @Return = 1;
END TRY
BEGIN CATCH
IF XACT_STATE() <> 0
ROLLBACK TRANSACTION;
SET @ErrorMostrar = 'Ocurrió un error al agregar el rol; 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_Sis_RolAdd'),
'; Línea: ', ERROR_LINE(),
'; Detalle: ', ERROR_MESSAGE()
);
RAISERROR(N'%s', 10, 1, @ErrorTecnico);
END CATCH;
END;
GO
Cuando el procedimiento use una transacción, debe incluir BEGIN TRANSACTION dentro de TRY y COMMIT TRANSACTION antes de establecer @Return = 1.