Implementar tratamento de erros T-SQL

Concluído

Um erro indica um problema ou problema notável que surge durante uma operação de banco de dados. Os erros podem ser gerados pelo Mecanismo de Banco de Dados do SQL Server em resposta a um evento ou falha no nível do sistema; Ou você pode gerar erros de aplicativo em seu código Transact-SQL.

Elementos de erros do mecanismo de banco de dados

Seja qual for a causa, cada erro é composto pelos seguintes elementos:

  • Número do erro - Número exclusivo que identifica o erro específico.
  • Mensagem de erro - Texto descrevendo o erro.
  • Gravidade - Indicação numérica de gravidade de 1 a 25.
  • Estado - Código de estado interno para a condição do mecanismo de banco de dados.
  • Procedimento - O nome do procedimento armazenado ou gatilho no qual o erro ocorreu.
  • Número da linha - Qual instrução no lote ou procedimento gerou o erro.

Erros do sistema

Os erros do sistema são predefinidos e você pode visualizá-los na visualização do sistema sys.messages . Quando ocorre um erro de sistema, o SQL Server pode tomar medidas corretivas automáticas, dependendo da gravidade do erro. Por exemplo, quando ocorre um erro de alta gravidade, o SQL Server pode colocar um banco de dados offline ou até mesmo interromper o serviço do mecanismo de banco de dados.

Erros personalizados

Você pode gerar erros no código Transact-SQL para responder a condições específicas do aplicativo ou para personalizar informações enviadas para aplicativos cliente em resposta a erros do sistema. Esses erros de aplicativo podem ser definidos em linha onde são gerados, ou você pode predefini-los na tabela sys.messages ao lado dos erros fornecidos pelo sistema. Os números de erro usados para erros personalizados devem ser 50001 ou superior.

Para adicionar uma mensagem de erro personalizada a sys.messages, use sp_addmessage. O usuário da mensagem deve ser membro das funções de servidor fixas sysadmin ou serveradmin.

Esta é a sintaxe sp_addmessage:

sp_addmessage [ @msgnum= ] msg_id , [ @severity= ] severity , [ @msgtext= ] 'msg' 
     [ , [ @lang= ] 'language' ] 
     [ , [ @with_log= ] { 'TRUE' | 'FALSE' } ] 
     [ , [ @replace= ] 'replace' ]

Aqui está um exemplo de uma mensagem de erro personalizada usando esta sintaxe:

sp_addmessage 50001, 10, N’Unexpected value entered’;

Além disso, você pode definir mensagens de erro personalizadas, os membros da função de servidor sysadmin também podem usar um parâmetro adicional, @with_log. Quando definido como TRUE, o erro também será registrado no log de aplicativos do Windows. Qualquer mensagem gravada no log de aplicativos do Windows também é gravada no log de erros do SQL Server. Seja criterioso com o uso da opção @with_log, porque os administradores de rede e sistema tendem a não gostar de aplicações que são excessivamente verbosas nos logs do sistema. No entanto, se o erro precisar ser capturado por um alerta, o erro deve antes de tudo ser gravado no registo de aplicações do Windows.

Observação

Não há suporte para a geração de erros do sistema.

As mensagens podem ser substituídas sem excluí-las primeiro usando a @replace opção = 'substituir'.

As mensagens são personalizáveis e diferentes podem ser adicionadas para o mesmo número de erro para vários idiomas, com base em um valor language_id.

Observação

As mensagens em inglês são language_id 1033.

Levantar erros usando RAISERROR

Tanto PRINT quanto RAISERROR podem ser usados para retornar informações ou mensagens de aviso aos aplicativos. RAISERROR permite que os aplicativos gerem um erro que pode ser detetado pelo processo de chamada.

RAISERROR

A capacidade de gerar erros no T-SQL facilita o tratamento de erros no aplicativo, porque ele é enviado como qualquer outro erro do sistema. RAISERROR é usado para:

  • Ajude a solucionar problemas de código T-SQL.
  • Verifique os valores dos dados.
  • Retornar mensagens que contenham texto variável.

Observação

Usar uma instrução PRINT é semelhante a gerar um erro de gravidade 10.

Aqui está um exemplo de uma mensagem de erro personalizada usando RAISERROR.

RAISERROR (N'%s %d', -- Message text,
    10, -- Severity,
    1, -- State,
    N'Custom error message number',
    2)

Quando acionado, ele retorna:

Custom error message number 2

No exemplo anterior, %d é um espaço reservado para um número e %s é um espaço reservado para uma cadeia de caracteres. Além disso, você deve observar que um número de mensagem não foi mencionado. Quando erros com cadeias de caracteres de mensagem são gerados usando essa sintaxe, eles sempre têm o número de erro 50000.

Gerar erros usando THROW

A instrução THROW oferece um método mais simples de gerar erros no código. Os erros devem ter um número de erro de pelo menos 50000.

LANÇAMENTO

THROW difere de RAISERROR de várias maneiras:

  • Os erros gerados pelo THROW são sempre de gravidade 16.
  • As mensagens retornadas por THROW não estão relacionadas a nenhuma entrada em sys.sysmessages.
  • Os erros gerados por THROW só causam a anulação da transação quando usados em conjunto com SET XACT_ABORT ON e a sessão é encerrada.
THROW 50001, 'An Error Occured',0

Capturar códigos de erro usando @@Error

O código de tratamento de erros mais tradicional em aplicativos do SQL Server foi criado usando @@ERROR. O tratamento de exceções estruturadas foi introduzido no SQL Server 2005 e fornece uma alternativa forte ao uso do @@ERROR. Será discutido na próxima lição. Uma grande quantidade de código de tratamento de erros existente do SQL Server é baseada em @@ERROR, por isso é importante entender como trabalhar com ele.

@@ERROR

@@ERROR é uma variável de sistema que contém o número de erro do último erro que ocorreu. Um desafio significativo com @@ERROR é que o valor que ele detém é rapidamente redefinido à medida que cada instrução adicional é executada.

Por exemplo, considere o seguinte código:

RAISERROR(N'Message', 16, 1);
IF @@ERROR <> 0
PRINT 'Error=' + CAST(@@ERROR AS VARCHAR(8));
GO

Você pode esperar que, quando o código é executado, ele retornará o número do erro em uma cadeia de caracteres impressa. No entanto, quando o código é executado, ele retorna:

Msg 50000, Level 16, State 1, Line 1
Message
Error=0

O erro foi gerado, mas a mensagem impressa foi "Erro = 0". Na primeira linha da saída, você pode ver que o erro, como esperado, foi na verdade 50000, com uma mensagem passada para RAISERROR. Isso ocorre porque a instrução IF que segue a instrução RAISERROR foi executada com êxito e fez com que o valor @@ERROR fosse redefinido. Por esse motivo, ao trabalhar com @@ERROR, é importante capturar o número de erro em uma variável assim que ela for levantada e, em seguida, continuar processando com a variável.

Observe o código a seguir que demonstra isso:

DECLARE @ErrorValue int;
RAISERROR(N'Message', 16, 1);
SET @ErrorValue = @@ERROR;
IF @ErrorValue <> 0
PRINT 'Error=' + CAST(@ErrorValue AS VARCHAR(8));

Quando esse código é executado, ele retorna a seguinte saída:

Msg 50000, Level 16, State 1, Line 2
Message
Error=50000

Agora, o número do erro é corretamente relatado.

Centralização do tratamento de erros

Um outro problema significativo com o uso de @@ERROR para tratamento de erros é que é difícil centralizar dentro do seu código T-SQL. O tratamento de erros tende a acabar espalhado por todo o código. Seria possível centralizar o tratamento de erros usando @@ERROR até certo ponto, usando rótulos e declarações GOTO. No entanto, isso seria mal visto pela maioria dos desenvolvedores hoje como uma prática de codificação pobre.

Criar alertas de erro

Para determinadas categorias de erros, os administradores podem criar alertas do SQL Server, pois desejam ser notificados assim que eles ocorrerem. Isso pode até se aplicar a mensagens de erro definidas pelo usuário. Por exemplo, talvez você queira gerar um alerta sempre que um log de transações for preenchido. Os alertas são comumente usados para chamar a atenção dos administradores para erros de alta gravidade (como a gravidade 19 ou superior).

Emissão de alertas

Alertas podem ser criados para mensagens de erro específicas. O serviço de alerta funciona registrando-se como um serviço de retorno de chamada com o serviço de log de eventos. Isso significa que os alertas só funcionam em erros registrados.

Há duas maneiras de fazer com que um erro gere um alerta: você pode usar a opção WITH LOG ao gerar o erro ou a mensagem pode ser alterada para torná-la registrada executando sp_altermessage. A opção WITH LOG afeta apenas a instrução atual. O uso do sp_altermessage altera o comportamento de erro para todos os usos futuros. Modificar erros do sistema via sp_altermessage só é possível a partir do SQL Server 2005 SP3 ou SQL Server 2008 SP1.