Files
Plataforma-de-desarrolladores/AGENTS_STORED_PROCEDURES.md
Jorge Luis caudillo esparza 6685ef63fb Initial commit
2026-07-14 11:15:57 -07:00

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, 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:

@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

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.