2

I have the need to run a .bat file to run a SQL command on demand, It needs to have an if nested within a for and the if should repeat until true.

What I have:

@echo off
cd "%UserProfile%\Desktop\Scripting\"

FOR /f "delims=" %%a in ('type queue.txt') DO (
:loop

  IF EXIST reset.sql (

  goto loop

  ) ELSE (

  ::Create SQL command
  echo USE dbname> reset.sql
  echo EXEC dbo.sp_ResetSubscription @ClientName = '%%a'>> reset.sql
  echo EXEC dbo.sp_RunClientSnapshot @ClientName = '%%a'>> reset.sql
  sqlcmd -i "reset.sql"

  if exist reset.sql del /f /q reset.sql
  )
)
if exist queue.txt del /f /q queue.txt

This bombs out when it hits the loop, if I move :loop from where it is to within the if statement it works fine, however that isn't much use.

What I need it to do is to keep looping until reset.sql does not exist but at the same time stay within the same iteration of the loop.

Myles Gray
  • 8,711
  • 7
  • 48
  • 70

2 Answers2

2

You should not ever GOTO a :label within a parenthesized block of code. See https://stackoverflow.com/a/8481978/1012053 - it deals with an IF() block, but the concept is the same for a FOR..DO() block. Performing a GOTO within a FOR..DO() will abort the remainder of the FOR iterations NOTE - a FOR /L loop will silently finish counting without actually processing the DO() clause

This modification should give you the behavior you are looking for.

@echo off
cd "%UserProfile%\Desktop\Scripting\"

FOR /f "delims=" %%a in ('type queue.txt') DO (
  call :waitForNoReset
  ::Create SQL command
  echo USE dbname> reset.sql
  echo EXEC dbo.sp_ResetSubscription @ClientName = '%%a'>> reset.sql
  echo EXEC dbo.sp_RunClientSnapshot @ClientName = '%%a'>> reset.sql
  sqlcmd -i "reset.sql"
  if exist reset.sql del /f /q reset.sql
)
if exist queue.txt del /f /q queue.txt
exit /b

:waitForNoReset
  if exist reset.sql goto :waitForNoReset
exit /b
Community
  • 1
  • 1
dbenham
  • 127,446
  • 28
  • 251
  • 390
0

I would try:

@echo off
cd "%UserProfile%\Desktop\Scripting\"

FOR /f "delims=" %%a in ('type queue.txt') DO (
:loop

  IF NOT EXIST reset.sql (

     ::Create SQL command
     echo USE dbname> reset.sql
     echo EXEC dbo.sp_ResetSubscription @ClientName = '%%a'>> reset.sql
     echo EXEC dbo.sp_RunClientSnapshot @ClientName = '%%a'>> reset.sql
     sqlcmd -i "reset.sql"

     if exist reset.sql del /f /q reset.sql
     goto endIter
   ) 

  goto loop
  :endIter 
 )

if exist queue.txt del /f /q queue.txt
Eystein Bye
  • 5,016
  • 2
  • 20
  • 18
  • That will not work for the same reasons the original will not work. See [my answer](http://stackoverflow.com/a/9018647/1012053) – dbenham Jan 26 '12 at 14:16