5

I'm running an SQL request in batch-file and I need to get the errorlevel as well as the output it gives. I've tried using :

for /f "tokens=*" %%i in ('%SQLCommand%') do ( ...

and in the 'do', if the errorlevel is 1, then I can do whatever I plan to do, but I can't seem to find a way to get the errorlevel from the result of the command. I'm also not sure if the errorlevel can change while in the loop, but that I was planning on testing it as so I would get a way to know if the command change the errorlevel.

CedL
  • 113
  • 2
  • 13
  • 2
    the `('command')` is executed in a separate process. This should answer your question. (Hint: errorlevel is lost, when the process ends) – Stephan May 18 '18 at 18:53
  • @Stephan Oh! Then i'm guessing i really can't control this other process to return any value. – CedL May 18 '18 at 18:58
  • 1
    correct (with a `for` loop). Alternative: `%SQLCommand% > output.txt` and `if %errorlevel% == 1 for /f "tokens=*" %%i in (output.txt) do ( ... ` – Stephan May 18 '18 at 19:02
  • @Stephan Yeah, that was the "Plan B" i was going for it wasn't possible. Guess I'll be going with it! Thank you! – CedL May 18 '18 at 19:04
  • `for /F %%L in ('%SQLCommand% ^& call echo %%^^ErrorLevel%%') do ( ... )` could perhaps be used to capture the `ErrorLevel` as well (although I'm not sure whether I appied escaping correctly as I can't test right now)... – aschipfl May 19 '18 at 13:34

1 Answers1

3

The problem here is that the command line assigned to environment variable SQLCommand is executed by FOR in a separate command process in background with cmd.exe /C and its output to handle STDOUT is captured by FOR and processed line by line. For that reason the exit code of the SQL command line cannot be evaluated in command process executing the batch file.

The most likely best solution is running the SQL command line in current command process with redirecting the output of the SQL command line into a temporary file, evaluating the exit code and processing the output according to exit code.

The batch file below demonstrates this solution. It can be started without an argument, with a valid file/folder name as first argument, or with an invalid file/folder name for watching error handling.

@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

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • del /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • pause /?
  • set /?
  • setlocal /?

See also the Stack Overflow questions:

Mofi
  • 46,139
  • 17
  • 80
  • 143