Olá pessoal,
Vocês já ouviram falar no RAISERROR?
Hoje, jogando fora algo de SQL, vamos falar dessa função.
O RAISERROR retorna uma mensagem, assim como a função PRINT, aos aplicativos. Porém, em forma de erro, ou seja, como uma Exception só que gerada pelo SQL.
Essa função pode ser usada para várias finalidades como: verificar problemas no código T-SQL, mostrar textos com variáveis ou fazer que, quando estiver num bloco TRY, a execução pule para o bloco CATCH.
A construção de uma função do RAISERROR é a seguinte:
ERRO:
Texto definido pelo usuário, número do erro definido pelo usuário (acima de 50.000 pela procedure sp_addmessage) ou uma variável do tipo CHAR ou VARCHAR.
GRAVIDADE:
Indica uma faixa de gravidade, que sobrepõe a definida usando o sp_addmessage.
ESTADO:
Utilizado para ajuda o usuário a encontrar onde o código está gerando erros. (Raramente vejo algo diferente de 1).
ARGUMENTOS:
Textos, variáveis a serem adicionados na mensagem de Erro.
Vamos aos Testes...
RAISERROR('Você gerou um Erro', 16, 1)
Erro simples... Agora vamos ver sendo utilizado em uma procedure, vamos inserir um usuário, porém, se ele já existir na base, deve-se retornar um erro.
CREATE PROCEDURE [dbo].[Usuario_Inserir]
@Nome VARCHAR(100)
@Email VARCHAR(100)
AS
BEGIN
IF NOT EXISTS (SELECT Email FROM Usuarios WHERE Email = @Email)
BEGIN
INSERT INTO [dbo].[Usuarios]
([Nome]
,[Email])
VALUES
(@Nome
,@Email)
END
ELSE
BEGIN
RAISERROR('Usuário já cadastrado', 16, 1)
END
END
Se estivéssemos criando uma aplicação .Net e tentássemos usar a procedure dentro de um TRY...CATCH... e caísse no RAISERROR então a execução iria para o bloco CATCH, e se pegássemos a mensagem de erro a mesma seria o texto adicionado acima.
Mas, caso tenha muitos erros do tipo, poderemos adicionar com a procedure sp_addmessage (que adiciona valores na tabela sys.messages) um erro acima de 50.000 (ao contrário é exibido um erro, esse erro agente não quer =P);
EXEC sp_addmessage 50010,
18,
'%s already registered',
'us_english'
EXEC sp_addmessage 50010,
18,
'Usuário %s já cadastrado',
'Português'
Bom, acima eu criei um erro em inglês e português, agora vou alterar a procedure que tinha criado.
ALTER PROCEDURE [dbo].[Usuario_Inserir]
@Nome VARCHAR(100),
@Email VARCHAR(100)
AS
BEGIN
IF NOT EXISTS (SELECT Email FROM Usuarios WHERE Email = @Email)
BEGIN
INSERT INTO [dbo].[Usuarios]
([Nome]
,[Email])
VALUES
(@Nome
,@Email)
END
ELSE
BEGIN
RAISERROR(50010, 16, 1, @Nome)
END
END
Podemos ver que na chamada do RAISERROR passamos a Id do erro que criamos e passamos um argumento no formato de String. (String: %s, Int: %d).
Talvez o mais interessante do RAISERROR seja as mensagens que ela pode retornar, mas, a gravidade também é interessante e podemos fazer algo diferente com ela.
Existe uma faixa de gravidade onde: 0 – 18: Pode ser definido por qualquer usuário. 19 – 25: Apenas sysadmin, esta precisa ser chamada com a opção WITH LOG, pois grava um erro no arquivo de LOG, além de ter a conexão com o cliente encerrada.
Por fim, deixo um exemplo com o uso em um TRY...CATCH do SQL, juntamente com o RAISERROR que possui uma gravidade acima de 19.
BEGIN TRY
PRINT 1
RAISERROR ('Aqui gerou Erro antes de imprimir 2',
22,
1
) WITH LOG
PRINT 2
END TRY
BEGIN CATCH
DECLARE @ErrorMessage NVARCHAR(4000);
DECLARE @ErrorSeverity INT;
DECLARE @ErrorState INT;
SELECT @ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE();
RAISERROR (@ErrorMessage,
@ErrorSeverity,
@ErrorState)
END CATCH
No lixo! Até mais.