Handling special characters in an external DATA file in the FOR command in a BATCH file

StackOverflow https://stackoverflow.com/questions/21477256

  •  05-10-2022
  •  | 
  •  

Question

I have a DATA file, which holds database-connection info in the following format (with | as delimiter):

DatabaseServerIp1|UserName1|Password1|DatabaseName1
DatabaseServerIp2|UserName2|Password2|DatabaseName2
DatabaseServerIp3|UserName3|Password3|DatabaseName3

And I have a batchfile which reads the contents of this file and uses the contents to execute a script on each of the databases in this file. This script works great in most cases, but runs into issues when one of the variables contains a special character like % or @.

I read online that I'm supposed to use "SETLOCAL EnableDelayedExpansion" and surround the variables with exclamation marks, but I can't get this to work. Some other posts also mentionned using quotes instead of exclamation marks, but I couldn't get this to work either.

I would like to avoid changing the contents of the DATA file (I don't want to add escape characters inside the DATA file).

The script in which I'd like to use this is:

rem ... more code here ...

FOR /F "eol== delims=| tokens=1,2,3,4" %%i IN (%DATABASEDATAFILE%) DO CALL :_ACTION %%i %%j %%k %%l
GOTO :_END

:_ACTION

IF "%1"=="" GOTO :EOF

SET IPSERVER=%1
SET USERNAME=%2
SET PASSWORD=%3
SET DATABASE=%4

sqlcmd -S%IPSERVER% -U%USERNAME% -P%PASSWORD% -d%DATABASE% -i%SCRIPTFILE% -o%RESULTFILE%

GOTO EOF

:_END

rem ... more code here ...

:EOF

How do I make this code handle special characters correctly?

Example: %-character in the password field.

As you might have guessed, I'm not the original creator of this batch file or the data file.

Était-ce utile?

La solution

The most of your suggestions (delayed expansion, quotes) are correct, but the order is important.

setlocal DisableDelayedExpansion
FOR /F "eol== delims=| tokens=1,2,3,4" %%i IN (%DATABASEDATAFILE%) DO (
   SET "IPSERVER=%%i
   SET "USERNAME=%%j"
   SET "PASSWORD=%%k"
   SET "DATABASE=%%l"

   CALL :ACTION
)
goto :EOF

:ACTION
setlocal EnableDelayedExpansion

sqlcmd -S!IPSERVER! -U!USERNAME! -P!PASSWORD! -d!DATABASE! -i!SCRIPTFILE! -o!RESULTFILE!

endlocal
goto :EOF

Autres conseils

@ECHO OFF
SETLOCAL
FOR /f "tokens=1-4delims=|" %%a IN (%DATABASEDATAFILE%) DO ECHO sqlcmd -S%%a -U%%b -P%%c -d%%d -i%SCRIPTFILE% -o%RESULTFILE%

GOTO :EOF

should do the trick. I've just ECHOed the SQL line produced - after verification, you'd need to change ECHO sqlcmd to sqlcmd to execute the sqlcmd.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top