124 lines
5.0 KiB
Markdown
124 lines
5.0 KiB
Markdown
# 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`, `DELETE` ni `MERGE` directamente 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>`.
|
|
- `PA` significa 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 ejemplo `Add`, `Update`, `List`, `Activate`, `Deactivate` o `Delete`.
|
|
- Ejemplos: `PA_Sis_UsuarioAdd`, `PA_Sis_UsuarioUpdate`, `PA_Sis_UsuarioList`, `PA_Sis_UsuarioActivate`, `PA_Sis_UsuarioDeactivate` y `PA_Sis_UsuarioDelete`.
|
|
|
|
## Parámetros y resultado obligatorios
|
|
|
|
Todos los procedimientos deben declarar:
|
|
|
|
```sql
|
|
@CveUsuarioEjecuta int,
|
|
@ErrorMostrar varchar(max) OUTPUT,
|
|
@ErrorTipo int OUTPUT,
|
|
@Return bit OUTPUT
|
|
```
|
|
|
|
- `@CveUsuarioEjecuta` identifica al usuario autenticado que ejecuta la operación.
|
|
- Al inicio, establecer `@ErrorMostrar = NULL`, `@ErrorTipo = 0` y `@Return = 0`.
|
|
- Establecer `@Return = 1` únicamente cuando la operación termine correctamente.
|
|
- `@ErrorTipo = 0`: sin error ni advertencia.
|
|
- `@ErrorTipo = 1`: error.
|
|
- `@ErrorTipo = 2`: advertencia.
|
|
- `@ErrorMostrar` contiene 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 ON` y `TRY/CATCH` en todos los procedimientos.
|
|
- Usar `SET XACT_ABORT ON` cuando exista una mutación o transacción.
|
|
- Iniciar la transacción dentro de `TRY`, confirmar sólo después del éxito y ejecutar rollback en `CATCH` cuando `XACT_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 `EXISTS` en lugar de `COUNT(*)`.
|
|
- En `CATCH`, generar un mensaje técnico separado con `ERROR_NUMBER()`, `ERROR_PROCEDURE()`, `ERROR_LINE()` y `ERROR_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 `DELETE` físico en procedimientos CRUD normales.
|
|
- Para borrar: `Borrado = 1` y `FechaBorrado = SYSDATETIME()`.
|
|
- Para restaurar: `Borrado = 0` y `FechaBorrado = NULL`.
|
|
- Las consultas normales deben filtrar `Borrado = 0` en 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
|
|
|
|
```sql
|
|
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`.
|