Implementar o tratamento estruturado de exceções

Concluído

Agora que você tem uma compreensão da natureza dos erros e do tratamento básico de erros no T-SQL, é hora de olhar para uma forma mais avançada de tratamento de erros. O tratamento de exceções estruturadas foi introduzido no SQL Server 2005.

Aqui, você verá como usá-lo e avaliará seus benefícios e limitações, incluindo o bloco TRY CATCH, o papel das funções de tratamento de erros e entendendo a diferença entre erros detetáveis e não detetáveis. Finalmente, você verá como os erros podem ser gerenciados e revelados quando necessário.

O que é a programação em bloco TRY/CATCH

O tratamento estruturado de exceções é mais poderoso do que o tratamento de erros com base na variável de sistema @@ERROR. Ele permite que você evite que o código seja repleto de código de tratamento de erros e centralize esse código de tratamento de erros. A centralização do código de tratamento de erros também significa que você pode se concentrar mais na finalidade do código do que no tratamento de erros que ele contém.

Bloco de código TRY e bloco de código CATCH

Ao usar o tratamento de exceções estruturadas, o código que pode gerar um erro é colocado dentro de um bloco TRY. Os blocos TRY são incluídos pelas instruções BEGIN TRY e END TRY .

Se ocorrer um erro detetável - a maioria dos erros pode ser detetada, o controle de execução se move para o bloco CATCH. O bloco CATCH é uma série de instruções T-SQL incluídas pelas instruções BEGIN CATCH e END CATCH .

Observação

Enquanto BEGIN CATCH e END TRY são instruções separadas, o BEGIN CATCH deve seguir imediatamente o END TRY.

Limitações atuais

Linguagens de alto nível geralmente oferecem uma construção try/catch/finally e são frequentemente usadas para liberar recursos implicitamente. Não há nenhum bloco FINALLY equivalente no T-SQL.

Entenda a diferença entre erros detetáveis e não detetáveis

É importante perceber que, embora os blocos TRY/CATCH permitam que você detete uma gama muito maior de erros do que poderia com @@ERROR, você não pode capturar todos os tipos.

Erros detetáveis vs. erros não detetáveis

Nem todos os erros podem ser detetados pelos blocos TRY/CATCH dentro do mesmo escopo em que o bloco TRY/CATCH existe. Muitas vezes, erros que não podem ser detetados no mesmo escopo podem ser detetados em um escopo circundante. Por exemplo, talvez não seja possível detetar um erro no procedimento armazenado que contém o bloco TRY/CATCH. No entanto, é provável que você detete esse erro em um bloco TRY/CATCH no código que chamou o procedimento armazenado onde o erro ocorreu.

Erros comuns não detetáveis

Exemplos comuns de erros não detetáveis são:

  • Erros de compilação, como erros de sintaxe, que impedem a compilação de um lote.
  • Problemas de recompilação em nível de declaração que geralmente estão relacionados à resolução de nomes adiados. Por exemplo, você pode criar um procedimento armazenado que se refira a uma tabela desconhecida. Um erro só é lançado quando o procedimento tenta resolver o nome da tabela para um objectid.

Como relançar erros usando THROW

Se a instrução THROW for usada num bloco CATCH sem parâmetros, ela voltará a lançar o erro que levou a execução a entrar no bloco CATCH. Você pode usar essa técnica para implementar o log de erros no banco de dados capturando erros e registrando seus detalhes e, em seguida, lançando o erro original para o aplicativo cliente, para que ele possa ser tratado lá.

Aqui está um exemplo de como relançar um erro.

BEGIN TRY
    -- code to be executed
END TRY
BEGIN CATCH
    PRINT ERROR_MESSAGE();
    THROW
END CATCH

Em algumas versões anteriores do SQL Server, não havia nenhum método para lançar um erro de sistema. Embora THROW não possa especificar um erro do sistema a ser gerado, quando usado sem parâmetros num bloco CATCH, THROW reativará tanto os erros do sistema quanto os erros do utilizador.

O que são funções de tratamento de erros

Os blocos CATCH disponibilizam as informações relacionadas com erros durante toda a duração do bloco CATCH. Isso inclui subescopos, como procedimentos armazenados, executados dentro do bloco CATCH.

Funções de tratamento de erros

Lembre-se de que, ao programar com @@ERROR, o valor mantido pela variável de sistema @@ERROR foi redefinido assim que a próxima instrução foi executada.

Outra vantagem importante do tratamento de exceções estruturadas no T-SQL é que uma série de funções de tratamento de erros foi fornecida e estas mantêm seus valores em todo o bloco CATCH. Funções separadas fornecem cada propriedade de um erro levantado.

Isso significa que você pode escrever procedimentos armazenados genéricos de tratamento de erros que ainda podem acessar as informações relacionadas a erros.

  • Os blocos CATCH disponibilizam as informações relacionadas com erros durante toda a duração do bloco CATCH.
  • @@Error é reiniciado quando a próxima instrução é executada.

Gerenciar erros no código

A integração do SQL CLR permite a execução de código gerenciado no SQL Server. Linguagens .NET de alto nível, como C# e VB, têm tratamento de exceções detalhado disponível para elas. Os erros podem ser detetados usando blocos padrão .NET try/catch/finally .

Erros no código gerenciado

Em geral, você pode querer detetar erros dentro do código gerenciado tanto quanto possível. É importante perceber, no entanto, que quaisquer erros não tratados no código gerenciado são passados de volta para o código T-SQL de chamada. Sempre que qualquer erro que ocorre no código gerenciado é retornado ao SQL Server, ele parecerá ser um erro 6522. Os erros podem ser aninhados e esse erro específico estará encobrindo a causa real do erro.

Outra causa rara, mas possível, de erros no código gerenciado seria que o código poderia executar uma instrução RAISERROR T-SQL por meio de um objeto SqlCommand.