quinta-feira, 26 de abril de 2007

Usando try...catch no SQL Server 2005

Olá.
Venho hoje falar sobre este novo recurso da linguagem Transact-SQL (T-SQL) do SQL Server 2005.

Nas versões anteriores do SQL Server a única maneira de se trabalhar com exceções era o famoso @@ERROR.
Usávamos este recurso principalmente quando tínhamos uma transação. Era comum que, após iniciarmos a transação, tivéssemos que incluir abaixo de cada linha com potencial de erro o seguinte código:

IF @@ERROR > 0
ROLLBACK TRANSACTION

O tratamento de erros desta maneira possuía várias desvantagens, dentre elas posso citar:

  • Ter de escrever este código em cada linha que poderia ocasionar em um erro;
  • A variável @@ERROR era reinicializada após qualquer outro comando;
  • Os erros não poderiam ser capturados e tratados pelo próprio código (procedure), ou seja, após realizarmos o “ROLLBACK” o erro era lançado para a próxima procedure ou para a aplicação da pilha;


A grande mudança no T-SQL é que agora podemos tratar os erros de um trecho de código quase da mesma forma que fazemos no VB.Net ou no C#.

O procedimento é bem simples:

  1. Iniciamos o bloco que pode retornar um erro que queremos tratar com “BEGIN TRY”;
  2. Escrevemos nosso código normalmente, inclusive com a inicialização da transação e o “COMMIT TRANSACTION” no final;
  3. Finalizamos o bloco com “END TRY”;
  4. Abrimos o bloco de tratamento de erros com “BEGIN CATCH”;
  5. Escrevemos nosso código de tratamento do erro;
  6. Fechamos o bloco de tratamento de erros com “END CATCH”;

É muito importante atentar para o fato de que, ao capturar uma exceção em um bloco CATCH, o SQL Server não a lança para quem chamou o código. Isto quer dizer que, se você necessitar que o erro seja lançado para o caller é necessário utilizar do nosso velho conhecido RAISERROR.

Veja um exemplo de código de como isto pode ser feito:

begin try
begin transaction
seu código vem aqui
commit transaction
end try
begin catch
declare
@ErrorMessage nvarchar(4000)
declare @ErrorSeverity int
declare @ErrorState int

select
@ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE()

rollback transaction

RAISERROR
(@ErrorMessage, @ErrorSeverity, @ErrorState)
end catch

Você notou as novas funções de erro?
Bem mais informativas que a antiga @@ERROR.

No SQL Server 2005, as seguintes funções são utilizadas para obter mais detalhes dos erros:

ERROR_NUMBER()
ERROR_SEVERITY()
ERROR_STATE()
ERROR_PROCEDURE()
ERROR_LINE()
ERROR_MESSAGE()

Além de fornecer detalhes sobre o erro ocorrido, estas funções têm como vantagem o fato de não serem reinicializadas após uma linha qualquer de comando executado, como acontecia com o @@ERROR.

A grande vantagem do TRY...CATCH é que, além de deixar o código mais robusto, podemos separar o que é a lógica do negócio do tratamento dos possíveis erros.

Diminuímos a quantidade de código escrito e temos uma melhor legibilidade.

Mais informações em Using TRY...CATCH in Transact-SQL.

Abraços e até o próximo post.

Nenhum comentário: