Calling sqlcmd.exe in batch file using variables causes error: "unexpected argument"

Calling sqlcmd.exe in batch file using variables causes error: "unexpected argument"

在 Windows 批处理文件中,这有效:

sqlcmd.exe -b -S xxMySqlServerNamexx -Q "BACKUP DATABASE xxMyDatabaseNamexx TO DISK='d:\data\xxMyDatabaseNamexx.bak' with init, compression"  

这样做:

set vSource_SqlServer="xxMySqlServerNamexx"      
sqlcmd.exe -b -S %vSource_SqlServer% -Q "BACKUP DATABASE xxMyDatabaseNamexx TO DISK='d:\data\xxMyDatabaseNamexx.bak' with init, compression"  

但是这个:

set vSource_SqlServer="xxMySqlServerNamexx"  
set vSource_SqlDbName="xxMyDatabaseNamexx"  
sqlcmd.exe -b -S %vSource_SqlServer% -Q "BACKUP DATABASE %vSource_SqlDbName% TO DISK='d:\data\xxMyDatabaseNamexx.bak' with init, compression"  

...导致错误:

Sqlcmd: 'xxMyDatabaseNamexx" TO DISK='d:\data\xxMyDatabaseNamexx.bak' with init, compression"': Unexpected argument. Enter '-?' for help.

如您所见,使用变量 %vSource_SqlDbName% 代替 xxMyDatabaseNamexx

令人窒息

是否有正确的方法以这种形式(我的意思是,是的,我可能应该使用 Powershell 或替代方法,但我有几个现有的批处理我更愿意将这种形式的文件转换为使用这种形式的变量,即使这不是完美的方式)?

set 语句没有取消引用它的参数。 所以 set a=b c 意味着 %a% 扩展为 b c,而 set a="b c" 意味着它扩展为 "b c".

所以在你的非工作示例中,你将双引号文本放在双引号字符串中,这是行不通的。

set 中删除引号,它应该可以工作。

设置变量最安全的方法是使用语法(如果启用 command extensions,这是 Windows 中的默认设置):

set "vSource_SqlDbName=xxMyDatabaseNamexx"

请注意整个表达式周围的引号,因此它们不会成为扩展值的一部分。 %vSource_SqlDbName% 因此扩展为 vSource_SqlDbName.