При выдаче команды резервного копирования в хранимой процедуре, которая использует try catch и динамический sql, сообщения об ошибках являются очень общими по сравнению с непосредственным выполнением команды резервного копирования.
Попробуйте / поймать в SP:
begin try
execute sp_executesql @sql; -- a backup command
end try
begin catch
print ERROR_MESSAGE(); -- save to log, etc.
end catch
Результаты в
50000: usp_Backup: 117: BACKUP DATABASE завершается ненормально.
где выданы необработанные команды:
backup DATABASE someDb to disk...
Результаты в лучших деталях:
Ошибка поиска - ошибка базы данных SQL Server: возникла неустранимая ошибка ввода-вывода в файле «H: \ FolderName \ Filename.bak:» 112 (на диске недостаточно места).
Есть ли способ перехватить эти детали в переменных внутри хранимой процедуры (для регистрации, передачи обратно вызывающей стороне, для логики повторения)? Кажется, подробности передаются по каналу сообщений, но я бы хотел, чтобы они были доступны в SP.
источник
Ответы:
Когда
BACKUP DATABASE
генерирует ошибку, на самом деле генерирует два. К сожалениюTRY/CATCH
, не может захватить первую ошибку; это только захватывает вторую ошибку.Я подозреваю, что вам лучше всего понять реальную причину неудачного резервного копирования - автоматизировать резервное копирование с помощью SQLCMD (с
-o
отправкой вывода в файл), SSIS, C #, PowerShell и т. Д. Все это даст вам гораздо больший контроль над захватом всех из ошибок.Ответ SO в комментарии предлагает использовать
DBCC OUTPUTBUFFER
- хотя это возможно, это совсем не похоже на детскую игру. Не стесняйтесь получать удовольствие от этой процедуры с сайта Эрланда Соммарскога , но, похоже, в сочетании с этим она не очень хорошо работаетTRY/CATCH
.Единственный способ, которым я, кажется, был в состоянии захватить сообщение об ошибке,
spGET_LastErrorMessage
- это если фактическая ошибка действительно сброшена. Если вы заключите его вTRY/CATCH
ошибку, ошибка будет проглочена, а хранимая процедура ничего не сделает:В SQL Server <2012 вы не можете повторно вызвать ошибку самостоятельно, но вы можете в SQL Server 2012 и новее. Итак, эти два варианта работают:
Или в 2012 и выше, это работает, но в значительной степени противоречит цели
TRY/CATCH
, так как исходная ошибка все еще появляется:Конечно, в обоих случаях ошибка по-прежнему выдается клиенту. Так что, если вы используете это,
TRY/CATCH
чтобы избежать этого, если нет какой-либо лазейки, о которой я не думаю, я боюсь, что вам придется сделать выбор ... либо предоставьте пользователю ошибку и сможете получить сведения о это или подавить как ошибку, так и фактическую причину.источник
Ну, я знаю, что это старый поток, и я знаю, что я собираюсь предложить извилистый хак, но на всякий случай, если он может кому-нибудь помочь, вот так: Так как эти ошибки резервного копирования регистрируются, вы можете использовать xp_readerrorlog в подвохе блок, чтобы очистить журнал для связанного сообщения (ошибка или информация). Вы можете поискать параметры xp_readerrorlog, но вкратце вы можете указать строку поиска и фильтр времени начала, которые полезны в этом случае. Не уверен, поможет ли это вашей логике повторения, но чтобы получить информацию или ошибки для регистрации, я придумал что-то вроде этого ...
НТН
источник
Вы можете записать подробности ошибки в таблицу. Вы также можете создать файл журнала, но для этого может потребоваться CLR или xp_cmdshell. Вы также можете отправлять почту базы данных, но это может вызвать проблемы со спамом и не является правильным журналом.
Таблица самая простая.
Посмотрите на пример Джереми Кадлека, приведенный в ссылке ниже:
http://www.mssqltips.com/sqlservertip/1152/standardized-sql-server-error-handling-and-centralized-logging/
источник
CATCH
. Это потому, что только последнее сообщение об ошибке возвращается вERROR_MESSAGE()
...