sqlcmd
возможно недостаточно.cmd.exe
в среде запланированной задачи может не найти исполняемый файл, используя local PATHEXT
и local PATH
переменные среды.Исполняемый файл должен быть указан с полным именем файла, то есть диск + путь + имя + расширение.Тогда пакетный файл больше не зависит от переменных среды PATH
и PATHEXT
, поскольку на все файлы ссылаются с полным именем файла.
for
выполняет указанную командную строку с запуском в фоновом режимедополнительный командный процесс с %ComSpec% /c
и указанной командной строкой.Это означает, что выполняется с Windows, установленной на диске C:
:
C:\Windows\System32\cmd.exe /c sqlcmd -j -S DOMAIN\SQLSERVER -U username -P password -d DBNAME -Q "UPDATE [DBNAME].[dbo].[table1] SET ColOne='V1_OFF' WHERE ColOne='V1'"
for
захватывает все, что записано для обработки STDOUT запущенного командного процесса.Строки захваченного вывода обрабатываются построчно на for
после того, как запуск cmd.exe
завершается сам.Сообщения об ошибках, выводимые запущенным cmd.exe
или командами / исполняемыми файлами, выполняемыми командным процессором Windows в фоновом режиме для обработки STDERR , перенаправляются для обработки STDERR командного процесса, обрабатывающего пакетный файл, и печатаются вприставка.Но при запуске командного файла в качестве запланированной задачи окно консоли отсутствует.Таким образом, сообщения об ошибках в этом случае не видны.
Командную строку for
можно легко изменить здесь, чтобы получать также сообщения об ошибках, записанные в C:\Apps\Debug.log
.
FOR /F "tokens=* USEBACKQ" %%F IN (`sqlcmd -j -S DOMAIN\SQLSERVER -U username -P password -d DBNAME -Q "UPDATE [DBNAME].[dbo].[table1] SET ColOne='V1_OFF' WHERE ColOne='V1' 2^>^&1"`) DO (
Microsoftстатья Использование операторов перенаправления команд поясняет 2>&1
.Два оператора >
и &
должны быть экранированы с помощью ^
, чтобы интерпретироваться как литеральные символы на командном процессоре Windows, анализирующем командную строку for
перед выполнением finally for
, которое выполняется следующим %ComSpec% /c
с указанной командойстрока, в которой 2^>^&1
уже изменена на 2>&1
.
Содержит ли файл журнала C:\App\Debug.log
с этой модификацией следующие две строки?
'sqlcmd' не распознанв качестве внутренней или внешней команды,
работоспособная программа или командный файл.
Да, тогда запускаемый cmd.exe
не найдет исполняемый файл с именем файла sqlcmd
.Лучшее решение - ссылаться на этот исполняемый файл с полным именем файла.См. Также: По какой причине «X не распознается как внутренняя или внешняя команда, работающая программа или пакетный файл»?
В противном случае sqlcmd
может выдать сообщение об ошибке, которое должнотеперь также в файле журнала C:\App\Debug.log
.
Можно также использовать следующую командную строку, чтобы фон cmd.exe
записывал сообщения об ошибках в отдельный файл журнала ошибок C:\App\Error.log
:
FOR /F "tokens=* USEBACKQ" %%F IN (`sqlcmd -j -S DOMAIN\SQLSERVER -U username -P password -d DBNAME -Q "UPDATE [DBNAME].[dbo].[table1] SET ColOne='V1_OFF' WHERE ColOne='V1'" 2^>C:\App\Error.log`) DO (
"tokens=* usebackq"
приводит к тому, что сначала удаляются все начальные горизонтальные табуляции и обычные пробелы в непустых строках с помощью for
, а затем проверяется, начинается ли оставшаяся строка с ;
, в этом случае строка также игнорируется инаконец, присваиваемую захваченную строку не начиная с ;
и удаляя начальные символы табуляции / пробелы для переменной цикла F
для дальнейшей обработки.
Лучше было бы использовать параметры usebackq^ delims^=^ eol^=
, не заключенные в двойные кавычки, что требуетэкранирование двух пробелов и двух знаков равенства с символом вставки ^
для интерпретации буквальных символов как cmd.exe
on разбирает командную строку перед выполнением for
.Режим разделения строк отключен, завершается с delims=
из-за определения пустого списка разделителей.И никакая строка, за исключением пустой строки, больше не игнорируется, поскольку символ конца строки изменен со значения по умолчанию ;
на отсутствие символа.
Наконец, пробел в строке echo
, оставленный оператору перенаправления >>
, также выводится echo
и по этой причине записывается как конечный пробел в файл журнала.Поэтому при печати строки с echo
, перенаправленной в файл, не должно быть свободного места до >
или >>
.Но нужно позаботиться об исключении пробела, оставленного оператору перенаправления. слово , оставленное оператору перенаправления, не должно быть 1
, 2
, ..., 9
, так как это приведет к перенаправлению вывода на эти пронумерованные дескрипторы в указанный файл вместо символа1
, 2
и т. Д. Поэтому, если неизвестный текст должен быть записан в файл, лучше сначала указать оператор перенаправления >
или >>
и полное имя файла, а затем команду echo
с текстом для вывода.См. Также: Почему команда ECHO выводит в файл дополнительное конечное пространство?
Три командные строки с echo
будут для этого пакетного файла:
ECHO Disabling the following...>> C:\App\Debug.log
ECHO - V1>> C:\Apps\Debug.log
>>C:\Apps\Debug.log ECHO %%F
following...
безопасен для правильной записи в файл, также как V1
.%%F
может быть просто 1
или строкой, заканчивающейся пробелом и одной цифрой, поэтому лучше указывать перенаправление сначала в последней командной строке echo
, чтобы окончательно выполнить cmd.exe
командной строкой ECHO %%F 1>>C:\Apps\Debug.log
.