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”.