Olá galera o/

Nesta postagem vou mostrar como fazemos tratamento de erros na linguagem T-SQL.

Como toda boa linguagem de programação o T-SQL também possui métodos para tratamento de erros e exceções durante a execução dos comandos. A linguagem T-SQL utiliza o TRY..CATCH semelhando ao utilizado na linguagem C#. Os tratamentos de erro foram inseridos no SQL Server a partir da versão 2005. Para trabalhar com erros no SQL os códigos devem estar entre as palavras chaves BEGIN TRY..END TRY e BEGIN CATCH..END CATCH. Podemos utilizar o tratamento de erro na construção de nossos objetos dentro do banco, como por exemplo stored procedures, triggers, fluxos de loop e etc.

Quando você esta construindo a lógica do seu código T-SQL, o código principal deve ser inserido no bloco BEGIN TRY, caso ocorra um erro ou exceção, a lógica de tratamento deve estar no bloco BEGIN CATCH. Os bloco TRY..CATCH devem sempre ser construídos juntos. Caso o bloco TRY não possua erros, o bloco é totalmente ignorado, porém, se o bloco TRY contiver um erro, o bloco CATCH será acionado.

Sintaxe:

BEGIN TRY
CODIGO_SQL
END TRY
BEGIN CATCH
CODIGO_SQL
END CATCH

Vamos exemplificar a execução do bloco Try Catch dividindo 10 por 2. Notem que, o código a ser executado fica no bloco BEGIN TRY..END TRY e o bloco do erro deve estar no BEGIN CATCH..END CATCH. Ao executar o código, percebam que, o resultado gerado foi o número 5, ou seja, o código funcionou conforme esperado e o bloco CATCH foi ignorado.

BEGIN TRY
	SELECT 10/2
END TRY
BEGIN CATCH
	PRINT 'ERROR NA DIVISÃO'
END CATCH

Vamos exemplificar dividindo 1 por 0, assim, forçando um erro no código. Ao executar o código, percebam que, o resultado foi vazio, ou seja, em vez de exibir ou retornar o erro, o bloco CATCH consumiu o erro.

BEGIN TRY
BEGIN TRY
	SELECT 1/0
END TRY
BEGIN CATCH
	PRINT 'ERROR NA DIVISÃO'
END CATCH

O objetivo de utilizar tratamento de erros é exibir o erro ocorrido para tomar uma ação sobre aquele determinado erro e assim corrigi-lo. É possível fazer investigar o erro com mais assertividade através de funções que exibem informações sobre o erro causado. O SQL Server possui algumas funções que fornecem informações sobre erro ocorrido. Vamos entender as principais:

  • ERROR_NUMBER: Retorna um número inteiro com o número do erro apresentado.
  • ERROR_MESSAGE: Retorna o texto da mensagem de erro.
  • ERROR_SEVERITY: Retorna a severidade (gravidade) do erro.
    • Para saber mais sobre os níveis de severidade do erro, acessar o link da Microsoft ao lado >> LINK <<
  • ERROR_STATE: Retorna o estado do erro.
  • ERROR_LINE: Retorna o número da linha que o erro aconteceu.
  • ERROR_PROCEDURE: Retorna o nome da procedure que aconteceu o erro se você estiver utilizando uma procedure, caso não estiver utilizando uma procedure é retornado o valor NULL.

Para saber quais erros e suas respectivas mensagens, você pode consultar a tabela sys.sysmessages. Notem que eu passei como filtro o msglangid = 1046, esse código exibe os erros exibidos no idioma Português Brasileiro, se você quiser ver o código de outros idiomas, deve realizar uma consulta na tabela sys.languages e verificar a coluna msglangid.

select *
from sys.sysmessages
where msglangid = 1046

select * 
from sys.syslanguages

Agora vamos utilizar as funções de erro em um exemplo bem legal. O cenário é o seguinte, vamos utilizar uma variável do tipo tabela para criar uma tabela chamada @tberror com 2 colunas (error_cod tinyint identity, error_name varchar(5)), vamos inserir um valor maior que o permitido na coluna error_name, ou seja, vamos forçar o erro e captura-lo utilizando o TRY.CATCH em conjunto com as funções de erros.

Se você ainda não sabe o que é variável do tipo tabela, ao lado segue uma postagem que desenvolvi explicando como utiliza-la no SQL Server. >> LINK <<

Vamos fazer o caminho feliz aonde o erro não acontecerá, ou seja, o código acaba no bloco BEGIN TRY..END TRY. Depois vamos ocasionar o erro, assim fazendo a chamada das funções de erro no bloco BEGIN CATCH..END CATCH. Lembre-se, como estamos utilizando variável do tipo tabela, temos que executar o código inteiro para que o mesmo seja executado com sucesso.

declare @tberror table (
error_cod tinyint identity, 
error_name varchar(5)
)

BEGIN TRY 
	insert into @tberror (error_name)
	values ('ABC')

	SELECT * FROM @tberror
END TRY
BEGIN CATCH
	SELECT ERROR_NUMBER() AS 'NUMERO DO ERRO', 
	ERROR_MESSAGE () AS 'MENSAGEM DE ERRO',
	ERROR_SEVERITY () AS 'GRAVIDADE DO ERRO',
	ERROR_STATE() AS 'ESTADO DO ERRO',
	ERROR_LINE() AS 'LINHA DE ERRO',
	ERROR_PROCEDURE () AS 'ERRO PROCEDURE'
END CATCH

Percebam que agora o código entrou no bloco do CATCH, além disso, as funções de erro capturaram o erro ocorrido ao tentar executar o insert no bloco TRY. Obs.: O erro exibido está em inglês, porque o meu SQL Server foi configurado no idioma inglês.

declare @tberror table (
error_cod tinyint identity, 
error_name varchar(5)
)

BEGIN TRY 
	insert into @tberror (error_name)
	values ('ABCDEF')

	SELECT * FROM @tberror
END TRY
BEGIN CATCH
	SELECT ERROR_NUMBER() AS 'NUMERO DO ERRO', 
	ERROR_MESSAGE () AS 'MENSAGEM DE ERRO',
	ERROR_SEVERITY () AS 'GRAVIDADE DO ERRO',
	ERROR_STATE() AS 'ESTADO DO ERRO',
	ERROR_LINE() AS 'LINHA DE ERRO',
	ERROR_PROCEDURE () AS 'ERRO PROCEDURE'
END CATCH

A partir da versão 2012 do SQL Server foi introduzida a função THROW, esta função lança uma exceção e transfere a execução para o bloco CATCH.

  • Obs.1: Se um código preceder (estiver antes) da função THROW, a mesma deve ser finalizada com PONTO E VÍRGULA (;).
  • Obs.2: Também possuímos a função RAISERROR para tratamento de erros, porém a própria Microsoft recomenda que seja utilizada a função THROW invés da RAISERROR.
    • Para mais informações sobre o RAISERROR, clicar no link ao lado. >> LINK <<

Abaixo a sintaxe do THROW.

THROW error_number, message, state
  • Parâmetros Opcionais do THROW
    • error_number: tem que estar entre 50.000 e 2.147.483.647, podendo ser uma constante ou uma variável.
    • message: descreve o erro apresentado, podendo ser uma string fixa ou uma variável.
    • state: indica o estado associado à mensagem, deve ser um tinyint entre 0 e 255, podendo ser uma variável ou uma constante.

Vamos aproveitar o código utilizado nas funções de erro, porém, substituindo as funções de erro pelo THROW. Vamos exemplificar o THROW sem os parâmetros opcionais e também mesmo tendo o erro personalizado com os parâmetros opcionais.

declare @tberror table (
error_cod tinyint identity, 
error_name varchar(5)
)

BEGIN TRY 
	insert into @tberror (error_name)
	values ('ABCDEF')

	SELECT * FROM @tberror
END TRY
BEGIN CATCH
	THROW;
END CATCH

THROW Personalizado

declare @tberror table (
error_cod tinyint identity, 
error_name varchar(5)
)

BEGIN TRY 
	insert into @tberror (error_name)
	values ('ABCDEF')

	SELECT * FROM @tberror
END TRY
BEGIN CATCH
	THROW 50001, 'Você inseriu um valor maior que o tamanho do campo',1
END CATCH

A postagem de hoje acaba por aqui, espero que tenham entendido como aplicar tratamento de erros nos seus códigos SQL. É de extrema importância construirmos códigos com tratamento de erro, para que assim possamos identificar e solucionar o erro (ou exceção) com mais assertividade e agilidade possível.

Desejo a todos uma boa leitura, boa prática e bons estudos.

Para quem quer estudar:

  • Para a Certificação Microsoft MTA Database Fundamentals | Banco de Dados Relacional e Linguagem T-SQL.
    • Segue o link do curso na Udemy. >> LINK <<
  • Sobre Bancos da Dados no Azure
    • Segue o link do curso na Udemy. >> LINK <<

Não se esqueçam de avaliar esta postagem através da ESTRELAS abaixo das redes sociais, isso vai me ajudar muito a melhorar as postagens.

Quem quiser mandar comentários, sugestões, criticas e complementos, fiquem a vontade, pois feedbacks positivos ou negativos engradecem meu conhecimento para que possa melhorar as postagem para vocês.

Até a próxima o/

Acessem nossas Redes Sociais: