Ниже test.bat
, который я ожидаю, чтобы вывести количество указанных c имен базы данных test
в экземпляре.
SET DB_SERVER_NAME=localhost
SET DB_DB_NAME=test
SET DB_SYSADMIN_LOGIN_NAME=sa
SET DB_SYSADMIN_LOGIN_PWD=test_sysad_pwd
for /F %%A in ('sqlcmd -S %DB_SERVER_NAME% -U %DB_SYSADMIN_LOGIN_NAME% -P %DB_SYSADMIN_LOGIN_PWD% -b -Q "set nocount on;SELECT COUNT(NAME) FROM SYS.DATABASES WHERE NAME = '%DB_DB_NAME%'"') do set DBCNT=%%A
ECHO %DBCNT% >> %~dp0\test.log 2>&1
%DBCNT%
иногда 1
или 0
в test.log
, что я ожидаю, но иногда %DBCNT%
не содержит числа.
Что не так?
Джеб и Мофи. Большое спасибо. Но текущая ситуация более запутанная.
Ниже приведен результат sqlcmd, напрямую вызываемый из командной строки.
"sqlcmd.exe" -S "{servername}" -U "sa" -P "{pwd}" -b -Q "set nocount on;SELECT COUNT(NAME) FROM SYS.DATABASES WHERE NAME = 'testdb'"
-----------
1
Ниже приведены вопросы, на которые указывает моя программа. Я сомневаюсь, что путь sqlcmd можно указать в среде клиента. Я думаю, что sqlcmd.exe иногда находится вне папки Windows.
A) Переменная должна быть инициализирована. Б) Используйте синтаксис «usebackq», когда команда содержит «». C)% ~ dp0 заканчивается backsla sh. (Не полагайтесь на исправление ядра.) D) Echo никогда не пишет что-то для обработки STDERR (стандартная ошибка). Используйте перенаправление непосредственно в файл журнала.
Ниже приведен пример программы:
REM /****************************************************************************/
SET DB_SERVER_NAME={servername}
SET DB_DB_NAME=testdb
SET DB_SYSADMIN_LOGIN_NAME=sa
SET DB_SYSADMIN_LOGIN_PWD={pwd}
REM /****************************************************************************/
chcp 437
REM original command
for /F %%A in ('sqlcmd -S %DB_SERVER_NAME% -U %DB_SYSADMIN_LOGIN_NAME% -P %DB_SYSADMIN_LOGIN_PWD% -b -Q "set nocount on;SELECT COUNT(NAME) FROM SYS.DATABASES WHERE NAME = '%DB_DB_NAME%'"') do set DBCNT=%%A
>>"%~dp0test.log" echo(#A#%DBCNT%
REM only use usebackq
SET DBCNT=0
for /F "usebackq" %%I in (`'sqlcmd -S %DB_SERVER_NAME% -U %DB_SYSADMIN_LOGIN_NAME% -P %DB_SYSADMIN_LOGIN_PWD% -b -Q "set nocount on;SELECT COUNT(NAME) FROM SYS.DATABASES WHERE NAME = '%DB_DB_NAME%'"'`) do set DBCNT=%%I
>>"%~dp0test.log" echo(#B#%DBCNT%
REM using remove single quotes several double quotes with absolute path sqlcmd
SET DBCNT=0
(for /F "usebackq" %%I in (`"C:\Program Files\Microsoft SQL Server\110\Tools\Binn\sqlcmd.exe" -S "%DB_SERVER_NAME%" -U "%DB_SYSADMIN_LOGIN_NAME%" -P "%DB_SYSADMIN_LOGIN_PWD%" -b -Q "set nocount on;SELECT COUNT(NAME) FROM SYS.DATABASES WHERE NAME = '%DB_DB_NAME%'"`) do set DBCNT=%%I) 2>>"%~dp0test.log"
>>"%~dp0test.log" echo(#C#%DBCNT%
REM using remove single quotes several double quotes, removing double quotes
SET DBCNT=0
(for /F "usebackq" %%I in (`'sqlcmd.exe -S "%DB_SERVER_NAME%" -U "%DB_SYSADMIN_LOGIN_NAME%" -P "%DB_SYSADMIN_LOGIN_PWD%" -b -Q "set nocount on;SELECT COUNT(NAME) FROM SYS.DATABASES WHERE NAME = '%DB_DB_NAME%'"'`) do set DBCNT=%%I) 2>>"%~dp0test.log"
>>"%~dp0test.log" echo(#D#%DBCNT%
REM using remove single quotes several double quotes
SET DBCNT=0
(for /F "usebackq" %%I in (`sqlcmd.exe -S "%DB_SERVER_NAME%" -U "%DB_SYSADMIN_LOGIN_NAME%" -P "%DB_SYSADMIN_LOGIN_PWD%" -b -Q "set nocount on;SELECT COUNT(NAME) FROM SYS.DATABASES WHERE NAME = '%DB_DB_NAME%'`) do set DBCNT=%%I) 2>>"%~dp0test.log"
>>"%~dp0test.log" echo(#E#%DBCNT%
Ниже приведен результат:
#A#1
#B#0
'C:\Program' is not recognized as an internal or external command,
operable program or batch file.
#C#0
#D#0