Deletado em 4 de fevereiro de 2009

Tudo sobre o RAISERROR

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.

OBS: Artigo publicado no linha de código.

Topo