Implementación del control de errores de T-SQL
Un error indica un problema o un problema importante que surge durante una operación de base de datos. El motor de base de datos de SQL Server puede generar errores en respuesta a un evento o error en el nivel del sistema; o bien, puede generar errores de aplicación en el código de Transact-SQL.
Elementos de errores del motor de base de datos
Independientemente de la causa, cada error se compone de los siguientes elementos:
- Número de error: número único que identifica el error específico.
- Mensaje de error : texto que describe el error.
- Gravedad : indicación numérica de gravedad de 1 a 25.
- Estado: código de estado interno para la condición del motor de base de datos.
- Procedimiento : nombre del procedimiento almacenado o desencadenador en el que se produjo el error.
- Número de línea: la instrucción del lote o procedimiento que generó el error.
Errores del sistema
Los errores del sistema están predefinidos y puede verlos en la vista del sistema sys.messages . Cuando se produce un error del sistema, SQL Server puede realizar una acción correctiva automática, en función de la gravedad del error. Por ejemplo, cuando se produce un error de gravedad alta, SQL Server puede desconectar una base de datos o incluso detener el servicio del motor de base de datos.
Errores personalizados
Puede generar errores en el código Transact-SQL para responder a condiciones específicas de la aplicación o personalizar la información enviada a las aplicaciones cliente como respuesta a errores del sistema. Estos errores de aplicación se pueden definir en línea donde se generan o puede predefinirlos en la tabla sys.messages junto con los errores proporcionados por el sistema. Los números de error usados para los errores personalizados deben ser 50001 o superior.
Para agregar un mensaje de error personalizado a sys.messages, use sp_addmessage. El usuario del mensaje debe ser miembro de los roles fijos de servidor sysadmin o serveradmin.
Esta es la sintaxis sp_addmessage:
sp_addmessage [ @msgnum= ] msg_id , [ @severity= ] severity , [ @msgtext= ] 'msg'
[ , [ @lang= ] 'language' ]
[ , [ @with_log= ] { 'TRUE' | 'FALSE' } ]
[ , [ @replace= ] 'replace' ]
Este es un ejemplo de un mensaje de error personalizado mediante esta sintaxis:
sp_addmessage 50001, 10, N’Unexpected value entered’;
Además, puede definir mensajes de error personalizados, los miembros del rol de servidor sysadmin también pueden usar un parámetro adicional, @with_log. Cuando se establece en TRUE, el error también se registrará en el registro de aplicaciones de Windows. Cualquier mensaje escrito en el registro de aplicaciones de Windows también se escribe en el registro de errores de SQL Server. Sea prudente con el uso de la opción @with_log porque a los administradores de red y del sistema tienden a no gustarles las aplicaciones que son verbosas en los registros del sistema. Sin embargo, si el error debe ser atrapado por una alerta, el error primero debe escribirse en el registro de aplicaciones de Windows.
Nota:
No se admite la generación de errores del sistema.
Los mensajes se pueden reemplazar sin eliminarlos primero mediante la @replace opción = 'replace'.
Los mensajes son personalizables y se pueden agregar diferentes para el mismo número de error para varios idiomas, en función de un valor de language_id.
Nota:
Los mensajes en inglés son language_id 1033.
Generación de errores mediante RAISERROR
Tanto PRINT como RAISERROR se pueden usar para devolver información o mensajes de advertencia a las aplicaciones. RAISERROR permite a las aplicaciones generar un error que el proceso de llamada podría detectar.
RAISERROR
La capacidad de generar errores en T-SQL facilita el control de errores en la aplicación, ya que se envía como cualquier otro error del sistema. RAISERROR se usa para:
- Ayuda para solucionar problemas de código T-SQL.
- Compruebe los valores de los datos.
- Devuelve mensajes que contienen texto variable.
Nota:
El uso de una instrucción PRINT es similar a generar un error de gravedad 10.
Este es un ejemplo de un mensaje de error personalizado mediante RAISERROR.
RAISERROR (N'%s %d', -- Message text,
10, -- Severity,
1, -- State,
N'Custom error message number',
2)
Cuando se desencadena, devuelve:
Custom error message number 2
En el ejemplo anterior, %d es un marcador de posición para un número y %s es un marcador de posición para una cadena. Además, debe tener en cuenta que no se mencionó un número de mensaje. Cuando se generan errores con cadenas de mensaje mediante esta sintaxis, siempre tienen el número de error 50000.
Generación de errores mediante THROW
La instrucción THROW ofrece un método más sencillo para generar errores en el código. Los errores deben tener un número de error de al menos 50000.
THROW
THROW difiere de RAISERROR de varias maneras:
- Los errores generados por THROW siempre son de gravedad 16.
- Los mensajes devueltos por THROW no están relacionados con ninguna entrada de sys.sysmessages.
- Los errores generados por THROW solo provocan la anulación de transacciones cuando se usan junto con SET XACT_ABORT ON y la sesión finaliza.
THROW 50001, 'An Error Occured',0
Captura de códigos de error mediante @@Error
La mayoría del código de control de errores tradicional en las aplicaciones de SQL Server se han creado mediante @@ERROR. El control estructurado de excepciones se introdujo en SQL Server 2005 y proporciona una alternativa sólida al uso de @@ERROR. Se analizará en la siguiente lección. Una gran cantidad de código de control de errores de SQL Server existente se basa en @@ERROR, por lo que es importante comprender cómo trabajar con él.
@@ERROR
@@ERROR es una variable del sistema que contiene el número de error del último error que se ha producido. Un desafío importante con @@ERROR es que el valor que contiene se restablece rápidamente a medida que se ejecuta cada instrucción adicional.
Por ejemplo, considere el código siguiente:
RAISERROR(N'Message', 16, 1);
IF @@ERROR <> 0
PRINT 'Error=' + CAST(@@ERROR AS VARCHAR(8));
GO
Es posible que espere que, cuando se ejecute el código, devolverá el número de error en una cadena impresa. Sin embargo, cuando se ejecuta el código, devuelve:
Msg 50000, Level 16, State 1, Line 1
Message
Error=0
Se produjo el error, pero el mensaje impreso era "Error=0". En la primera línea de la salida, puede ver que el error, como se esperaba, era realmente 50000, con un mensaje pasado a RAISERROR. Esto se debe a que la instrucción IF que sigue a la instrucción RAISERROR se ejecutó correctamente y provocó que se restablezca el valor de @@ERROR. Por este motivo, al trabajar con @@ERROR, es importante capturar el número de error en una variable tan pronto como se genere y, a continuación, continuar con el procesamiento con la variable.
Examine el código siguiente que muestra esto:
DECLARE @ErrorValue int;
RAISERROR(N'Message', 16, 1);
SET @ErrorValue = @@ERROR;
IF @ErrorValue <> 0
PRINT 'Error=' + CAST(@ErrorValue AS VARCHAR(8));
Cuando se ejecuta este código, devuelve la salida siguiente:
Msg 50000, Level 16, State 1, Line 2
Message
Error=50000
El número de error se notifica correctamente ahora.
Centralización del control de errores
Otro problema importante con el uso de @@ERROR para el control de errores es que es difícil centralizar dentro del código T-SQL. El control de errores tiende a acabar disperso en todo el código. Sería posible centralizar el control de errores mediante @@ERROR en cierta medida, mediante etiquetas y instrucciones GOTO. Sin embargo, la mayoría de los desarrolladores de hoy lo desaprobarían como una mala práctica de codificación.
Creación de alertas de error
Para determinadas categorías de errores, los administradores pueden crear alertas de SQL Server, ya que desean recibir notificaciones tan pronto como se produzcan. Esto incluso se puede aplicar a los mensajes de error definidos por el usuario. Por ejemplo, es posible que quiera generar una alerta cada vez que se llene un registro de transacciones. Las alertas se suelen usar para atraer errores de gravedad alta (como la gravedad 19 o superior) a la atención de los administradores.
Generación de alertas
Las alertas se pueden crear para mensajes de error específicos. El servicio de alertas lo que hace es registrarse como un servicio de devolución de llamada con el servicio de registro de eventos. Esto significa que las alertas solo funcionan en errores registrados.
Hay dos maneras de generar una alerta: puede usar la opción WITH LOG al generar el error o se puede modificar el mensaje para que se registre ejecutando sp_altermessage. La opción WITH LOG solo afecta a la instrucción actual. El uso de sp_altermessage cambia el comportamiento de error para todo el uso futuro. La modificación de errores del sistema a través de sp_altermessage solo es posible desde SQL Server 2005 SP3 o SQL Server 2008 SP1 en adelante.