SQL Server e Stored Procedures – Tratando exceções

Complicando um pouco

Seguindo a estrutura de trabalho do post anterior, vamos brincar um pouco com lançamento e tratamento de erros.

Lançando mensagens e exceções

Usando .NET, nós podemos usar o comando “Throw” para lançar exceções conforme achamos necessário.

O Sql também pode fazer isso, usando o comando RAISERROR.

RAISERROR é usado para devolver mensagens a aplicativos usando o mesmo formato que um erro do sistema ou mensagem de aviso gerada pelo Mecanismo de banco de dados do SQL Server.

Seus parâmetros básicos são:

  1. Id da mensagem (caso uma mensagem já esteja registrada no banco)
  2. Mensagem do erro (caso não seja registrada no banco)
  3. Severidade do erro
  4. Estado

Se você informar o Id de mensagem, não precisa passar a mensagem e vice versa.

A severidade do erro indicará quando cairemos num bloco de exceção ou se apenas mostraremos a mensagem. Se for menor ou igual a 10, apenas exibiremos a mensagem. Se for maior que 10, indicamos que o erro é grave e geramos exceção.

Vamos forçar alguns erros e ver o que acontece, na prática:

CREATE PROCEDURE usp_GenerateError
AS BEGIN

	DECLARE @i int
	SET @i = 9

	DECLARE @Msg VARCHAR(40)

	WHILE @i < 14
	BEGIN

		IF @i < 11
		BEGIN
			set @Msg = 'Erro...'
		END
		ELSE
		BEGIN
			set @Msg = 'Erro grave! Fujam pras montanhas!'
		END

		print @i

		RAISERROR(@Msg,@i,1)
		set @i = @i + 1

	END

END

Executando essa SP:

Mensagem em vermelho raramente é coisa boa pra quem programa. Inclusive, se não tratarmos essa exceção no SQL, ela cairá para a aplicação, no try/catch da linguagem que você utilizar, ou pior, diretamente na aplicação:

Tratando exceções no SQL

Nós também temos TRY/CATCH no SQL Server, a partir da versão 2005. Vejamos o que a documentação diz sobre a sintaxe:

BEGIN TRY
     { sql_statement | statement_block }
END TRY
BEGIN CATCH
     [ { sql_statement | statement_block } ]
END CATCH
[ ; ]

Bem simples né? Usando no nosso exemplo anterior:

ALTER PROCEDURE [dbo].[usp_GenerateError]
AS BEGIN

	DECLARE @i int
	SET @i = 9

	DECLARE @Msg VARCHAR(40)

	BEGIN TRY

		WHILE @i < 14
		BEGIN

			IF @i < 11
			BEGIN
				set @Msg = 'Erro...'
			END
			ELSE
			BEGIN
				set @Msg = 'Erro grave! Fujam pras montanhas!'
			END

			print @i

			RAISERROR(@Msg,@i,1)
			set @i = @i + 1

		END
	END TRY
	BEGIN CATCH

		print ''
		print 'Erro ocorreu!'
		print 'Mensagem: ' + ERROR_MESSAGE()
		print 'Procedure: ' + ERROR_PROCEDURE()

	END CATCH

END

A nossa nova saída será essa:

Muito melhor sem as mensagens em vermelho! Perceba que o try/catch só agiu quando a variável tinha o valor 11. Os erros anteriores foram meramente expostos no console.

Agora que nós já sabemos algumas coisas sobre exceções em procedures, vamos adiante, num exemplo um pouco mais prático.

Juntando as peças

Já perdi muitos fios de cabelo com procedures que não eram executadas corretamente, tudo por falta de dados.

Dependendo do seu Design Pattern (padrão de projeto), poderíamos colocar uma verificação dentro dela, lançando exceção caso algum parâmetro esteja invalidado.

No nosso banco de dados, imagine que eu quero consultar todos os presentes de uma dada categoria. É só enviar o id da categoria e colocar no where.

Eu posso querer um erro se eu enviar um id de categoria inexistente para a pesquisa. Usando nossos conhecimentos de sql, stored procedure e exceções:

CREATE PROCEDURE usp_EncontrarPresentesDeUmaCategoria
	@cat_id INT
AS BEGIN

	--para verificar se o Id existe mesmo
	DECLARE @isIdExistente INT
	SET @isIdExistente = (select COUNT(C.cat_id) FROM Categorias c where c.cat_id = @cat_id)

	IF(@isIdExistente = 0)
	BEGIN
		--lançando a exceção
		RAISERROR('Id de categoria não existente!',11,1)
	END

	SELECT
				p.pres_id,
				p.pres_nome,
				p.pres_desc
	FROM		Presentes p
	WHERE		p.pres_cat_id = @cat_id

END

Exemplo bobo, mas com técnicas que podem ser úteis a nós.

Concluindo

Tratar erros numa stored procedure é tão simples como no asp.net. Às vezes pode ser mais prático “enterrar” o erro por lá, do que trazer algo inútil para a nossa aplicação.

Mais informações:

Até a próxima!

Anúncios

2 pensamentos sobre “SQL Server e Stored Procedures – Tratando exceções

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

w

Conectando a %s