Обработка ошибок с помощью пакетного файла и Sqlcmd
У меня есть пакетный файл, который запускает несколько запросов SELECT с использованием sqlcmd, помещает результаты в текстовые файлы и загружает эти файлы на FTP-сервер. Что все работает так, как должно, а именно так, как мне нравится, что нужно работать.
Мне было интересно, что я буду делать в случае ошибки. Скажем, кто-то меняет структуру данных базы данных, на которую я нажимаю, и не уведомляет меня. Если бы я запустил инструкцию SELECT sqlcmd и опустил результат в текстовый файл, я бы просто получил текстовый файл с ошибкой, который затем перешел бы прямо на FTP, как будто ничего не случилось. (Я протестировал это.)
Я хотел бы иметь возможность проверять ошибки, возникающие из sqlcmd - тайм-ауты, плохие учетные данные, неверный запрос и т.д., я просто не уверен, как это делается или что такое "лучшая практика". Я всегда мог попробовать обходить выходной текстовый файл и искать ошибки, которые, как мне кажется, могут произойти, но это проблематично по ряду причин.
У кого-нибудь есть опыт с этим, что они хотели бы поделиться?
Ответы
Ответ 1
Вы можете проверить errorlevel
, возвращенный с SQLCMD
, чтобы узнать, не сработало ли оно.
sqlcmd -b <yourscript>
IF ERRORLEVEL 1 goto err_handler
goto done
:err_handler
REM handle the error here
:done
REM script completion code here
Ответ 2
Возможно, я начну с размещения возвращаемых значений в вашем SQL, например:
DECLARE @IsBored bit = 1
... do work ...
SELECT 0 -- Success!
Вы можете сделать это немного дальше и использовать блоки TRY/CATCH для ловушки ошибок и возврата кода ошибки. С помощью SQLCMD вы можете использовать код возврата из вашего SQL в качестве кода выхода приложения, например:
sqlcmd -b -S ServerName -E -d DbName -q "EXIT(EXEC dbo.YourProc)"
-o "C:\Logs\output.log" -u
Если вы управляете своими вызовами SQLCMD с помощью чего-то вроде планировщика, вы можете принять меры на основе кодов возврата из SQLCMD. Поскольку вы просто используете пакетные файлы, я думаю, вы можете сделать что-то вроде этого:
@ECHO OFF
sqlcmd -b -S ServerName -E -d DbName -q "EXIT(EXEC dbo.YourProc)"
-o "C:\Logs\output.log" -u
IF %ERRORLEVEL% NEQ 0 ECHO "Error"
Удачи!
Ответ 3
for %%G in (*.sql) do (sqlcmd /S %sqlhost% /d %sqldbname% -E -b -i "%%G" >> output.txt if ERRORLEVEL 1 exit)
Выше код будет проходить через все *.sql в папке. Если ошибка встречается в любом из script, ошибка будет регистрироваться в файле output.txt и немедленно остановит пакетный процесс.
Ответ 4
Я построил minilanguage в python, чтобы решить подобную проблему. Используя библиотеку подпроцессов, вы можете запустить свой код через sqlcmd, затем получить вывод и любые коды ошибок. Разбирайте результат перед тем, как поместить его в свой текстовый файл, и при необходимости перейдите в состояние исправления ошибок. Эти состояния могут изменять код или параметры и повторять отправку через sqlcmd. Если все остальное не удается, напишите человеку.
Конечно, поскольку я использовал такой питон, я вообще не интересовался sqlcmd и просто использовал библиотеки python odbc для прямого подключения к базе данных. Я мог бы отменить мои транзакции, если у меня был катастрофический сбой, запустить его в интерактивном режиме или с помощью командного файла и т.д. И т.д.
Это куча работы. Для более упрощенной проверки ошибок просто добавьте фильтр в ваш конвейер, скажем, grep или awk. Или сверните свой собственный с помощью flex.