Dan*_*Dan 1 sql-server batch-file sqlcmd
我正在使用SQLCMD来获取表中的行数,但我也想知道查询是否遇到错误.
我使用的sqlcmd看起来像这样:
sqlcmd -S %server% -U %user% -P %pass% -b -Q "select count(*) from %table%"
Run Code Online (Sandbox Code Playgroud)
如果有效,它将返回:
-----------
10205
(1 rows affected)
Run Code Online (Sandbox Code Playgroud)
(注意,-------上面有一个空行,我没有指定列名.)
如果我传入一个不存在的表,我得到以下响应:
Msg 208, Level 16, State 1, Server devServer, Line 1
Invalid object name 'dbo.no_table'.
Run Code Online (Sandbox Code Playgroud)
由于我有-b标志,我可以检查ERRORLEVEL的值(在本例中为1).
要存储count变量,我一直在使用以下行:
for /F %%i in ('sqlcmd -S %server% -U %user% -P %pass% -b -Q "select count(*) from %table%" ^| findstr /r "[^(][0-9]"') do SET /a rec_count=%%i
Run Code Online (Sandbox Code Playgroud)
在for之后,%errorlevel%返回0.即使在do内,errorlevel也是0.
是否有任何简单的方法来运行sqlcmd,如果没有错误则存储计数,如果有错误则打印两行?
由FOR/F执行的命令通过新的CMD会话隐式执行.例如,with for /f %a in ('echo hello') do ...,执行的命令变为C:\Windows\system32\cmd.exe /c echo hello.
您的命令正确设置了ERRORLEVEL,但是一旦子CMD会话终止并且控制权返回到您的批处理脚本,该值就会丢失.
因此,该/b选项对您没有任何好处,可以放弃.
您可以通过添加-h -1选项来抑制标题信息.
您可以(1 rows affected)通过为命令添加前缀来禁止显示消息set nocount on;
您可以添加该-r 1选项以使错误消息显示在stderr而不是stdout上.这将阻止FOR/F处理任何错误,并且错误消息将显示在屏幕上.
您可以在执行命令之前清除rec_count变量.如果出现错误,它将保持未定义,否则如果没有错误,它将包含计数.
set "rec_count="
for /f %%A in (
'sqlcmd -S %server% -U %user% -P %pass% -h -1 -r 1 -Q "set nocount on;select count(*) from %table%"'
) do set "rec_count=%%A"
if not defined rec_count echo There was an error!
Run Code Online (Sandbox Code Playgroud)
您可能考虑的另一件事是使用SQLCMD识别的环境变量作为您的服务器,用户名和密码.然后,您将不必使用-S,-U或-P选项.如果批处理脚本运行许多SQLCMD命令,这尤其方便.
set "sqlcmdServer=YourServer"
set "sqlcmdUser=YourUserName"
set "sqlcmdPassword=YourPassword"
set "rec_count="
for /f %%A in (
'sqlcmd -h -1 -r 1 -Q "set nocount on;select count(*) from %table%"'
) do set "rec_count=%%A"
if not defined rec_count echo There was an error!
Run Code Online (Sandbox Code Playgroud)