我正在批处理文件中运行 SQL 请求,我需要获取错误级别及其给出的输出。我尝试过使用:
for /f "tokens=*" %%i in ('%SQLCommand%') do ( ...
在“do”中,如果错误级别为1,那么我可以执行我计划执行的任何操作,但我似乎无法找到从命令结果中获取错误级别的方法。我也不确定错误级别在循环中是否可以改变,但我计划对其进行测试,这样我就可以知道命令是否会改变错误级别。
这里的问题是分配给环境变量
SQLCommand
的命令行由FOR在后台的单独命令进程中使用cmd.exe /C
执行,其处理STDOUT的输出由FOR捕获并处理行按行。因此,无法在执行批处理文件的命令进程中评估 SQL 命令行的退出代码。
最可能的最佳解决方案是在当前命令进程中运行 SQL 命令行,将 SQL 命令行的输出重定向到临时文件,评估退出代码并根据退出代码处理输出。
下面的批处理文件演示了此解决方案。它可以在没有参数的情况下启动,使用有效的文件/文件夹名称作为第一个参数,或者使用无效的文件/文件夹名称来监视错误处理。
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "OutputFile=%TEMP%\%~n0.tmp"
if "%~1" == "" ( set "DirArg=%TEMP%" ) else set "DirArg=%~1"
set "SQLCommand=dir /A /B "%DirArg%""
%SQLCommand% >"%OutputFile%" 2>nul
echo/
if errorlevel 1 (
echo An error occurred on execution of command:
echo/
echo %SQLCommand%
echo/
echo Exit code is: %ERRORLEVEL%
goto EndBatch
)
echo Execution of command was successful. The output is:
echo/
for /F "usebackq delims=" %%I in ("%OutputFile%") do echo %%I
:EndBatch
del "%OutputFile%"
endlocal
echo/
pause
为了了解所使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并仔细阅读每个命令显示的所有帮助页面。
del /?
echo /?
endlocal /?
for /?
goto /?
if /?
pause /?
set /?
setlocal /?
另请参阅 Stack Overflow 问题:
可以用
%ERRORLEVEL%
获得 for /f
,正如 aschipfl
在评论中指出的那样,但这很棘手,我在 dostips.com 论坛上找到了 this
,现在我得到了命令中的错误号,因此使用该代码作为基础我做了这样的事情:
@echo off
setlocal EnableDelayedExpansion
for /f "tokens=*" %%i in ('%command% ^|^| call echo ERROR_NUMBER%%^^^^errorlevel%%') do (
set OutputLine=%%i
if /i "!OutputLine:~0,12!" == "ERROR_NUMBER" (
set ERRNB=!OutputLine:ERROR_NUMBER=!
echo The error number was: !ERRNB!
)
)
请注意,我使用的是
EnableDelayedExpansion
,%command%
只是将要执行的命令,^|^|
用于转义pipes
字符,并在上一个命令失败时执行,剩下的就是一种方法要在 dostips.com 论坛 %%^^^^errorlevel%%
中获取错误号 Dave Benham
说这只是一个 hack
:
它并不是真的在逃避什么。这是一个推迟了的黑客行为 变量的扩展。
请记住,在命令行上下文中,%DoesNotExist% 的结果 是%不存在%。另请记住,任何字符之前都有插入符号 结果该字符被保留。它不一定是一个 特殊字符。
在扩展过程中插入符号被视为变量名称的一部分 阶段。假设我们有一个名为“myVar”的变量。然后一个命令 像 call echo %^myVar% 这样的行语句,尝试扩展变量 CALL 之前有“%^myVar%”,但它不存在。然后插入符是 删除(m 被保留),剩下 %myVar%。然后 在 CALL 之后,它会再次尝试并正确扩展正确命名的 变量。
当然,如果存在名为“^myVar”的变量,上述操作将会失败。但 插入符号通常不用于变量名称。
戴夫·贝纳姆