SQL SERVER – Gravando erros

Neste artigo veremos uma forma rápida e fácil de gravar informações no SQL Server 2008, porém, ainda podemos utilizar o mesmo código no SQL Server 2005 realizando algumas alterações no código, pois o SQL Server 2005 não tem o comando Try Catch.

Ocorrerem erros em uma aplicação não é uma coisa que queremos, porém, ela acontece e devemos saber quando ocorre. Hoje vou mostrar como gravar os erros com poucas linhas de código.

Primeiro, vamos criar a tabela para guardar os erros:

CREATE TABLE dbo.TBLogError(
	LogErrorID  	INT IDENTITY(1,1),
	Number  	INT,
	Severity  	INT,
	State  		INT,
	DataBaseName 	VARCHAR(128) CONSTRAINT TBLogErrorDFDataBaseName DEFAULT DB_NAME(),
	NameProcedure  VARCHAR(100),
	Line  		INT,
	Message  	VARCHAR(500),
	RegisterDate  	SMALLDATETIME CONSTRAINT TBLogErrorDFRegisterDate DEFAULT GETDATE()
)

Uma breve explicação dos campos:

  • LogErrorID: número sequencial com o ID dos erros cadastrados;
  • Number: número do erro do SQL Server;
  • Severity: gravidade do erro;
  • State: estado do erro;
  • NameProcedure: nome da procedure;
  • DataBaseName: nome da banco de dados (é útil nos caso em que você concentra todos os erros em uma única tabela, mas se você possuir um tabela para cada DataBase, pode desconsiderar esta coluna);
  • Line: linha que ocorreu o erro;
  • Message: mensagem de erro do SQL Server;
  • RegisterDate: Data que ocorreu o erro.

Agora vamos criar a Procedure:

-------------------------------------------------------------------------------
-- <summary>
--    Procedure que salva os erros ocorridos no banco de dados.
--    Salva os detalhes do erro e a data que o mesmo ocorreu
--    Retorna um ID como o numero do erro
-- </summary>
-- <history>
--     [Carlos Eduardo Barbosa]     01/04/2012    Created
-- </history>
-------------------------------------------------------------------------------
CREATE PROCEDURE [dbo].[SPLogError]
AS
SET NOCOUNT ON
IF ERROR_NUMBER() IS NOT NULL
BEGIN
    INSERT INTO dbo.TBLogError
               (Number
               ,Severity
               ,State
               ,NameProcedure
               ,Line
               ,Message
    )
         VALUES
               (ERROR_NUMBER()
               ,ERROR_SEVERITY()
               ,ERROR_STATE()
               ,ERROR_PROCEDURE()
               ,ERROR_LINE()
               ,ERROR_MESSAGE()
    )
END
SELECT @@IDENTITY AS ErrorID

Quando programamos uma procedure, devemos colocar o código dentro de blocos Try Catch para podemos tratar os erros.

Segue um exemplo:

CREATE PROCEDURE [dbo].[SPErrorCreate]
AS

SET NOCOUNT ON

BEGIN TRY
	SELECT 1/0
END TRY
BEGIN CATCH
	EXEC dbo.SPLogError
END CATCH

Nesta procedure, forçamos uma divisão por zero, dentro do bloco Try, e no bloco Catch executamos a procedure, para que no caso de erro ele guarde as informações. Agora, vamos executar a procedure.

EXEC dbo.SPErrorCreate

Após a execução, temos a seguinte saída no SQL Server:

Ao executarmos a procedure, ele nos retorna o ErrorID 5. Agora vamos consultar os dados da tabela TBLogError:

SELECT * FROM dbo.TBLogError

Ao executarmos a consulta, vemos que foram gravados os dados do erro de divisão por zero.

A procedure SPLogError retorna um ID do erro na coluna “LogErrorID”. Com essa informação poderíamos realizar diversas funcionalidades, tais como:

  • Enviar à aplicação Front-End o ID do erro, assim, quando o usuário entrar em contato com o helpdesk sobre o problema ele terá mais informações sobre o problema dando assim um atendimento melhor ao usuário;
  • Criar uma Trigger ou Job que verifique esta tabela e avise o DBA.

Obs.: Poderíamos pegar informações sobre o erro através de um join com a tabela sys.messages,como no código abaixo:

SELECT
		L.LogErrorID,
		L.Number,
		L.Message,
		M.text
FROM
	TBLogError AS L INNER JOIN sys.messages AS M
		ON L.Number = M.message_id
		AND M.language_id = 1033

Verificando a diferença de informações através das colunas “Message” e “text”, podemos ver que acabamos perdendo alguns detalhes do erro, por exemplo, se pegarmos a linha do LogErrorID igual a 3 temos a seguinte informação na coluna “text”:

“Cannot insert the value NULL into column ‘%.*ls’, table ‘%.*ls’; column does not allow nulls. %ls fails.”

Já as informações da coluna “Message” tem:

“Cannot insert the value NULL into column ‘GeraErroID’, table ‘DBTest.dbo.TBGeraErro’; column does not allow nulls. INSERT fails.”.

Como podemos ver, se gravarmos a mensagem de erro diretamente na coluna “Message” temos mais detalhes sobre ele, como o nome da tabela que ocorreu o erro, a “DBTest.dbo.TBGeraErro”.

Deixe um comentário