Ao emitir um comando de backup em um procedimento armazenado que usa um try catch e sql dinâmico, as mensagens de erro são muito gerais quando comparadas à execução direta do comando de backup.
Try / Catch dentro de SP:
begin try
execute sp_executesql @sql; -- a backup command
end try
begin catch
print ERROR_MESSAGE(); -- save to log, etc.
end catch
Resulta em
50000: usp_Backup: 117: BACKUP DATABASE está sendo finalizado de forma anormal.
wheareas emitindo o comando raw:
backup DATABASE someDb to disk...
Resultados em melhores detalhes:
Erro de pesquisa - Erro no banco de dados do SQL Server: Ocorreu um erro irrecuperável de E / S no arquivo "H: \ FolderName \ Filename.bak:" 112 (não há espaço suficiente no disco.).
Existe uma maneira de capturar esses detalhes em variáveis dentro do procedimento armazenado (para registrar, retornar ao chamador, para repetir a lógica)? Parece que os detalhes estão chegando no canal de mensagens, mas eu gostaria que eles estivessem disponíveis no SP.
fonte
Respostas:
Quando
BACKUP DATABASE
gera um erro, na verdade gera dois. InfelizmenteTRY/CATCH
não é capaz de capturar o primeiro erro; ele captura apenas o segundo erro.Eu suspeito que sua melhor aposta para capturar a verdadeira razão por trás de um backup com falha é automatizar seus backups através do SQLCMD (com
-o
saída para enviar para um arquivo), SSIS, C #, PowerShell etc. Tudo isso lhe dará um controle muito maior sobre a captura de todos os dos erros.A resposta do SO no comentário sugere o uso
DBCC OUTPUTBUFFER
- embora seja possível, isso não parece brincadeira de criança. Sinta-se à vontade para se divertir com este procedimento no site de Erland Sommarskog , mas isso ainda não parece funcionar bem em combinação comTRY/CATCH
.A única maneira pela qual pareci conseguir capturar a mensagem de erro
spGET_LastErrorMessage
é se o erro real for gerado. Se você o envolver,TRY/CATCH
o erro será engolido e o procedimento armazenado não fará nada:No SQL Server <2012, você não pode gerar o erro novamente, mas no SQL Server 2012 e mais recente. Portanto, essas duas variações funcionam:
Ou em 2012 e acima, isso funciona, mas em grande parte anula o objetivo de
TRY/CATCH
, uma vez que o erro original ainda é gerado:Nos dois casos, o erro ainda é gerado para o cliente, é claro. Portanto, se você estiver usando
TRY/CATCH
para evitar isso, a menos que haja alguma brecha em que não esteja pensando, receio que você tenha que fazer uma escolha ... ou dê ao usuário o erro e seja capaz de capturar detalhes sobre ou suprimir o erro e o motivo real.fonte
Bem, eu sei que esse é um encadeamento antigo, e sei o que estou prestes a propor é um hack complicado, mas para o caso de ajudar alguém, aqui vai: Como esses erros de backup são registrados, você pode usar xp_readerrorlog na captura bloco para raspar o log da mensagem relacionada (erro ou informação). Você pode procurar no google por parâmetros xp_readerrorlog, mas, em suma, pode especificar uma string de pesquisa e um filtro de horário de início que sejam úteis nesse caso. Não tenho certeza se isso ajudaria sua nova tentativa de lógica, mas para capturar informações ou erros no registro, criei algo assim ...
HTH
fonte
Você pode registrar os detalhes do erro em uma tabela. Você também pode criar um arquivo de log, mas isso pode exigir um CLR ou xp_cmdshell. Você também pode enviar correio do banco de dados, mas isso pode causar problemas de spam e não é um log adequado.
A tabela é mais simples.
Veja o exemplo de Jeremy Kadlec fornecido no link abaixo:
http://www.mssqltips.com/sqlservertip/1152/standardized-sql-server-error-handling-and-centralized-logging/
fonte
CATCH
. Isso ocorre porque somente a última mensagem de erro é retornada emERROR_MESSAGE()
...