在 Windows 批处理中 - 如何用转义单引号替换单引号以提供给 SQL
In Windows batch - how do I replace single quote with escape single quote to feed SQL
在我的 Windows 批处理文件中,我有以下 SQL 语句:
FOR /F "eol=; tokens=1,2,3,4,5,6* delims=, " %a in (myfile.txt) do(
sqlcmd -SmYSerbver -Uhhh -P12345 -dmyDB_Admin -Q"insert into tableA (UserID,FirstName,LastName,Email,DisplayName,OrgUnit,LoadDate) values('%%a','%%b','%%c','%%d','%%e','%%f',getdate())"
)
一个用户的姓氏是 "O'Brien" - 我的变量 %%c 被评估为 O'Brien。
如何操作才能让%%c被计算为"O''Brien"?
您需要一个临时变量来进行字符串替换,因为相关语法不能直接应用于 for
变量,例如 %%c
。为此,需要启用 delayed variable expansion,并且需要使用 !!
而不是 %%
来扩展临时变量。
下面说明了如何使用临时变量 c_tmp
为 %%c
中的值完成此操作:
setlocal EnableDelayedExpansion
for /F "eol=; tokens=1,2,3,4,5,6* delims=, " %%a in (myfile.txt) do (
set "c_tmp=%%c" & set "c_tmp=!c_tmp:'=''!"
sqlcmd -SmYSerbver -Uhhh -P12345 -dmyDB_Admin -Q"insert into tableA (UserID,FirstName,LastName,Email,DisplayName,OrgUnit,LoadDate) values('%%a','%%b','!c_tmp!','%%d','%%e','%%f',getdate())"
)
endlocal
当%%c
包含字符串O'Brien
时,c_tmp
最终将包含O''Brien
。
当然你也可以通过相应地修改命令set "c_tmp=!c_tmp:'=''!"
来做其他替换。
如果 sqlcmd 无法插入,也许你可以用 \
转义单引号,比如 O\'brian
。
如果文件包含不用于分隔值的单引号,那么您可以替换中间文件中的所有匹配项。
(
echo O'Brian1a, O'Brian1b, O'Brian1c, O'Brian1d, O'Brian1e, O'Brian1f
echo O'Brian2a, O'Brian2b, O'Brian2c, O'Brian2d, O'Brian2e, O'Brian2f
echo O'Brian3a, O'Brian3b, O'Brian3c, O'Brian3d, O'Brian3e, O'Brian3f
)>%tmp%\myfile.tmp
(
for /f "delims=" %%i in (%tmp%\myfile.tmp) do (
set "i=%%i"
setlocal enabledelayedexpansion
echo !i:'=\'!
)
)>%tmp%\int-myfile.tmp
for /f "tokens=1-6 delims=, " %%a in (%tmp%\int-myfile.tmp) do (
echo '%%a','%%b','%%c','%%d','%%e','%%f'
)
输出:
'O\'Brian1a','O\'Brian1b','O\'Brian1c','O\'Brian1d','O\'Brian1e','O\'Brian1f'
'O\'Brian2a','O\'Brian2b','O\'Brian2c','O\'Brian2d','O\'Brian2e','O\'Brian2f'
'O\'Brian3a','O\'Brian3b','O\'Brian3c','O\'Brian3d','O\'Brian3e','O\'Brian3f'
作为最后的手段,您始终可以选择用哪个字符替换行中的字符:echo !i:'=\'!
在我的 Windows 批处理文件中,我有以下 SQL 语句:
FOR /F "eol=; tokens=1,2,3,4,5,6* delims=, " %a in (myfile.txt) do(
sqlcmd -SmYSerbver -Uhhh -P12345 -dmyDB_Admin -Q"insert into tableA (UserID,FirstName,LastName,Email,DisplayName,OrgUnit,LoadDate) values('%%a','%%b','%%c','%%d','%%e','%%f',getdate())"
)
一个用户的姓氏是 "O'Brien" - 我的变量 %%c 被评估为 O'Brien。
如何操作才能让%%c被计算为"O''Brien"?
您需要一个临时变量来进行字符串替换,因为相关语法不能直接应用于 for
变量,例如 %%c
。为此,需要启用 delayed variable expansion,并且需要使用 !!
而不是 %%
来扩展临时变量。
下面说明了如何使用临时变量 c_tmp
为 %%c
中的值完成此操作:
setlocal EnableDelayedExpansion
for /F "eol=; tokens=1,2,3,4,5,6* delims=, " %%a in (myfile.txt) do (
set "c_tmp=%%c" & set "c_tmp=!c_tmp:'=''!"
sqlcmd -SmYSerbver -Uhhh -P12345 -dmyDB_Admin -Q"insert into tableA (UserID,FirstName,LastName,Email,DisplayName,OrgUnit,LoadDate) values('%%a','%%b','!c_tmp!','%%d','%%e','%%f',getdate())"
)
endlocal
当%%c
包含字符串O'Brien
时,c_tmp
最终将包含O''Brien
。
当然你也可以通过相应地修改命令set "c_tmp=!c_tmp:'=''!"
来做其他替换。
如果 sqlcmd 无法插入,也许你可以用 \
转义单引号,比如 O\'brian
。
如果文件包含不用于分隔值的单引号,那么您可以替换中间文件中的所有匹配项。
(
echo O'Brian1a, O'Brian1b, O'Brian1c, O'Brian1d, O'Brian1e, O'Brian1f
echo O'Brian2a, O'Brian2b, O'Brian2c, O'Brian2d, O'Brian2e, O'Brian2f
echo O'Brian3a, O'Brian3b, O'Brian3c, O'Brian3d, O'Brian3e, O'Brian3f
)>%tmp%\myfile.tmp
(
for /f "delims=" %%i in (%tmp%\myfile.tmp) do (
set "i=%%i"
setlocal enabledelayedexpansion
echo !i:'=\'!
)
)>%tmp%\int-myfile.tmp
for /f "tokens=1-6 delims=, " %%a in (%tmp%\int-myfile.tmp) do (
echo '%%a','%%b','%%c','%%d','%%e','%%f'
)
输出:
'O\'Brian1a','O\'Brian1b','O\'Brian1c','O\'Brian1d','O\'Brian1e','O\'Brian1f'
'O\'Brian2a','O\'Brian2b','O\'Brian2c','O\'Brian2d','O\'Brian2e','O\'Brian2f'
'O\'Brian3a','O\'Brian3b','O\'Brian3c','O\'Brian3d','O\'Brian3e','O\'Brian3f'
作为最后的手段,您始终可以选择用哪个字符替换行中的字符:echo !i:'=\'!