Controlar errores en procedimientos almacenados remotos entre servidores

Al ejecutar lotes y procedimientos almacenados remotos desde una instancia local de SQL Server en un cliente, puede experimentar errores de anulación de lote e instrucción:

  • Cuando se produce un error de anulación de instrucción, la instrucción que motivó el error se termina, pero la ejecución del lote o el procedimiento almacenado remoto continúa.

  • Cuando se produce un error de anulación de lote, se termina la ejecución del lote o el procedimiento almacenado remoto.

  • Cuando los lotes y los procedimientos almacenados remotos se ejecutan en el ámbito de un bloque TRY, los errores de anulación de lote pueden controlarse por medio de la construcción TRY…CATCH.

El comportamiento de los lotes y los procedimientos almacenados remotos que resultan de errores de anulación de lote e instrucción dependerá de la configuración de SET XACT_ABORT en el servidor local.

SET XACT_ABORT se ha desactivado

Si SET XACT_ABORT se ha desactivado (OFF) en el servidor local, los errores de anulación de instrucción en el procedimiento almacenado remoto se propagan como errores de anulación de instrucción del servidor local al cliente. Sólo se termina la instrucción que ha motivado el error. El cliente recibe mensajes de error que corresponden a los errores de anulación de instrucción. Además, si el procedimiento almacenado remoto se ejecuta hasta completarse, @@ERROR devuelve 0. Si los errores se producen en el ámbito del bloque TRY, la ejecución continúa y el bloque CATCH no se invoca.

Los errores de anulación de lote en el procedimiento almacenado remoto se propagan del servidor local al cliente. La instrucción EXECUTE que llamó al procedimiento almacenado remoto se termina, pero el lote o el procedimiento almacenado que incluía la instrucción continúa ejecutándose. Por tanto, @@ERROR devuelve el código de error que corresponde al error que finalizó el procedimiento almacenado remoto y el valor devuelto por el procedimiento almacenado es NULL. Cuando el procedimiento almacenado remoto que genera un error se ejecuta en el ámbito de un bloque TRY en el servidor local, el error hace que el control se pase al bloque CATCH con información acerca del último error en el servidor remoto.

Para solucionar errores, ejecute un procedimiento almacenado remoto desde el bloque TRY de una construcción TRY…CATCH. Si el procedimiento almacenado remoto no se completa correctamente, la ejecución saltará al bloque CATCH asociado en el servidor local con información acerca del último error en el servidor remoto. Si el procedimiento almacenado remoto se completa correctamente, la ejecución continúa en el bloque TRY en el servidor local y el valor devuelto por el procedimiento almacenado puede utilizarse.

Al ejecutar un procedimiento almacenado remoto fuera del ámbito de un bloque TRY, también puede examinar @@ERROR al final del procedimiento almacenado remoto para determinar si se ha completado. Si @@ERROR es 0, el procedimiento almacenado remoto se ejecutó correctamente y el valor devuelto puede utilizarse. Si @@ERROR no es 0, el procedimiento almacenado remoto no se ejecutó correctamente y el valor devuelto no puede utilizarse.

SET XACT_ABORT se ha activado

Si SET XACT_ABORT se ha activado (ON) en el servidor local, la configuración se propaga al servidor vinculado. Todos los errores de anulación de lote e instrucción en el procedimiento almacenado remoto se convierten a errores de anulación de lote en el servidor local. Por tanto, la ejecución del lote o el procedimiento almacenado que llamó al procedimiento almacenado remoto se termina junto con el procedimiento almacenado remoto. Cuando el procedimiento almacenado remoto que genera un error se ejecuta en el ámbito de un bloque TRY en el servidor local, el error hace que el control se pase al bloque CATCH con información acerca del último error en el servidor remoto.

Cuando un procedimiento almacenado remoto se ejecuta fuera del ámbito de un bloque TRY, no podrá examinar el valor de @@ERROR para determinar que un error de lote se produjo porque la instrucción que sigue a la instrucción EXECUTE no se ejecuta. Por tanto, debe ejecutar un procedimiento almacenado remoto desde el bloque TRY de una construcción TRY…CATCH. Si el procedimiento almacenado remoto no se completa correctamente, la ejecución saltará al bloque CATCH asociado en el servidor local con información acerca del último error en el servidor remoto. Si el procedimiento almacenado remoto se completa correctamente, la ejecución continúa en el bloque TRY en el servidor local y el valor devuelto por el procedimiento almacenado puede utilizarse.

RAISERROR y TRY…CATCH

Llamar a RAISERROR con una gravedad inferior a 20 desde un procedimiento almacenado remoto provoca un error de anulación de instrucción en el servidor remoto. Una construcción TRY…CATCH en el servidor local sólo controla errores de anulación de lote. Si un procedimiento almacenado remoto llama a RAISERROR con una gravedad inferior a 20 y el procedimiento almacenado remoto se encuentra en el ámbito de un bloque TRY en el servidor local, RAISERROR no hace que el control se pase al bloque CATCH de la construcción TRY…CATCH. No obstante, RAISERROR con una gravedad de 20 o superior en el servidor remoto rompe la conexión y la ejecución en el servidor local se pasa al bloque CATCH.