Tratando erros em procedimentos armazenados remotos de servidor para servidor

Quando você executa procedimentos armazenados e lotes de uma instância local do SQL Server para um cliente, pode experimentar erros de anulação da instrução e do lote:

  • Quando um erro de anulação da instrução ocorre, a instrução que provocou o erro é terminada, mas a execução do procedimento armazenado remoto ou do lote continua.

  • Quando um erro de anulação de lote ocorre, a execução de todo o procedimento armazenado ou lote termina.

  • Quando procedimentos armazenados remotos e lotes são executados dentro do escopo de um bloco TRY, erros de anulação do lote podem ser tratados pela construção TRY…CATCH.

O comportamento de procedimentos armazenados remotos e lotes resultante dos erros de anulação da instrução e do lote depende da configuração de SET XACT_ABORT do servidor local.

SET XACT_ABORT está OFF

Se SET XACT_ABORT estiver OFF no servidor local, todos os erros de anulação de instrução no procedimento armazenado remoto serão propagados como erros de anulação de instrução pelo servidor local ao cliente. Apenas a instrução que provocou o erro é terminada. O cliente recebe mensagens de erro que correspondem aos erros de anulação da instrução. Além disso, se o procedimento armazenado remoto executar até ser concluído, o @@ERRO retornará 0. Se o erro ocorrer dentro do escopo de um bloco TRY, a execução continuará e o bloco CATCH não será chamado.

Todos os erros de anulação de lote no procedimento armazenado remoto são propagados pelo servidor local ao cliente. A instrução EXECUTE que chamou o procedimento armazenado remoto termina, mas a execução do lote ou do procedimento armazenado que continha a instrução EXECUTE continua. Portanto @@ERROR retorna o código de erro que corresponde ao erro que terminou o procedimento armazenado remoto e o valor de retorno do procedimento armazenado é NULL. Quando o procedimento armazenado remoto que gera um erro é executado dentro do escopo de um bloco TRY no servidor local, o erro faz com que o controle seja passado para o bloco CATCH com informações sobre o último erro no servidor remoto.

Ao solucionar problemas de erros, execute um procedimento armazenado remoto de dentro do bloco TRY de uma construção TRY...CATCH. Se o procedimento armazenado remoto não for concluído com êxito, a execução saltará para o bloco CATCH associado no servidor local com informações sobre o último erro no servidor remoto. Se o procedimento armazenado remoto não for concluído com êxito, a execução continuará dentro do bloco TRY no servidor local e o valor de retorno do procedimento armazenado remoto poderá ser usado.

Como alternativa, ao executar um procedimento armazenado remoto fora do escopo de um bloco TRY, examine @@ERROR no final do procedimento armazenado remoto para determinar se o procedimento remoto está concluído. Se @@ERROR for 0, o procedimento armazenado remoto foi executado com êxito e o valor de retorno do procedimento armazenado remoto poderá ser usado. Se @@ERROR não for zero, o procedimento armazenado remoto não foi concluído com êxito e o valor de retorno do procedimento armazenado remoto poderá ser usado.

SET XACT_ABORT está ON

Se SET XACT_ABORT estiver ON no servidor local, a configuração será propagada ao servidor vinculado. Todos os erros de anulação de instrução e lote no procedimento armazenado remoto são convertidos em erros de anulação de lote no servidor local. Portanto a execução do lote ou procedimento armazenado que chamou o procedimento armazenado remoto é terminada junto com o procedimento armazenado remoto. Quando o procedimento armazenado remoto que gera um erro é executado dentro do escopo de um bloco TRY no servidor local, o erro faz com que o controle seja passado para o bloco CATCH com informações sobre o último erro no servidor remoto.

Quando um procedimento armazenado remoto é executado fora do escopo de um bloco TRY, não é possível examinar o valor de @@ERROR para determinar se um erro de lote ocorreu porque a instrução após a instrução EXECUTE não executa. Portanto você deve executar um procedimento armazenado remoto de dentro do bloco TRY de uma construção TRY…CATCH. Se o procedimento armazenado remoto não for concluído com êxito, a execução saltará para o bloco CATCH associado no servidor local com informações sobre o último erro no servidor remoto. Se o procedimento armazenado remoto for concluído com êxito, a execução continuará dentro do bloco TRY no servidor local e o valor de retorno do procedimento armazenado remoto poderá ser usado.

RAISERROR e TRY...CATCH

Chamar RAISERROR com severidade menor do que 20 de dentro de um procedimento armazenado remoto provoca um erro de anulação da instrução no servidor remoto. Uma construção TRY...CATCH no servidor local trata apenas erros de anulação de lote remoto. Se um procedimento armazenado remoto chamar RAISERROR com severidade menor do que 20 e o procedimento armazenado remoto tiver escopo dentro de um bloco TRY no servidor local, o RAISERROR não fará com que o controle seja passado para o bloco CATCH da construção TRY…CATCH. No entanto RAISERROR com severidade 20 ou maior no servidor remoto interrompe a conexão e a execução no servidor local passa para o bloco CATCH.