viernes, 13 de enero de 2012

Manejo de excepciones en SQL 2012

Antes que nada quiero saludar a todo el mundo luego de un mes de descanzo totalmente alejado de la pc! Ahora con todas las ganas de comenzar el 2012! Ahora a comenzar con el artículo.
En SQL 2008R2 o inferior la forma que teniamos de hacer el manejo de errores era utilizando el TRY y CATCH y luego en caso de ser necesario generar un error con RAISE ERROR. Cualquiera que esté familiarizado con el paradigma de objetos también lo está con el concepto de "lanzar excepciones". Este paso es lo que se ha implementado en esta nueva versión de SQL con la instrucción THROW.
Veamos un ejemplo de como manejabamos las excepciones antes:
-- =============================================
-- Create:        Andrés Aiello
-- Create date: 13/01/12
-- Description: Ejemplo de manejo de errores en SQL2012
-- =============================================

BEGIN TRY
 SELECT 1/0
END TRY
BEGIN CATCH
    DECLARE @ErrMsg nvarchar(4000), @ErrSeverity int
    SELECT @ErrMsg = ERROR_MESSAGE(),
        @ErrSeverity = ERROR_SEVERITY()

    RAISERROR(@ErrMsg, @ErrSeverity, 1)
END CATCH
GO


En cambio ahora con esta nueva instrucción sería:
-- =============================================
-- Create:        Andrés Aiello
-- Create date: 13/01/12
-- Description: Ejemplo de manejo de errores en SQL2012
-- =============================================

BEGIN TRY
 SELECT 1/0
END TRY
BEGIN CATCH
     THROW 51000, 'Mensaje de error a elección!', 1;
END CATCH
GO


Nuestra lógica no sufrió grandes cambios pero esto permite empezar a pensar en un paradigma de excepciones nuestro código.
Algunas diferencias entre el comportamiento de una y otra son:
RAISE ERROR
  • El error debe estar definido en la sys.messages
  • Los mensajes pueden utilizar el caracter % para ser parametrizados
  • Se puede definir la severidad del error, siendo esta cualquier número, incluyendo las mas graves
  • No se puede arrojar en cadena (hacia los llamadores) la excepción. Cuando se genera una nueva "pisa" la anterior
En cambio con la nueva instrucción THROW
  • El mensaje de error se define al momento de lanzar la excepción
  • Los mensajes NO pueden ser parametrizados. Tener en cuenta que al generarse en el momento los mensajes, esto no debería ser un gran problema
  • La severidad del error es siempre la misma, severidad 16
  • Un sp que captura una excepción puede relanzarla tal como en cualquier entorno de objetos
A mi ver es algo muy cómodo. Lo bueno es que no deberán salir todos corriendo a cambiar su código porque aún se mantendrá compatibilidad con ambas.
Espero que les haya servido.

Para mas info:
http://msdn.microsoft.com/en-us/library/ee677615%28v=sql.110%29.aspx