Sql 转义传递到xp_cmdshell的命令参数到dtexec

Sql 转义传递到xp_cmdshell的命令参数到dtexec,sql,tsql,sql-server-2008,stored-procedures,ssis,Sql,Tsql,Sql Server 2008,Stored Procedures,Ssis,我正在使用存储过程远程调用SSIS包,并调用xp_cmdshell: declare @cmd varchar(5000) set @cmd = '"C:\Program Files (x86)\Microsoft SQL Server\100\DTS\Binn\dtexec.exe" /Rep E /Sql Package /SET \Package.Variables[User::ImportFileName].Value;c:\foo.xlsx' print @cmd exec xp_cm

我正在使用存储过程远程调用SSIS包,并调用xp_cmdshell:

declare @cmd varchar(5000)
set @cmd = '"C:\Program Files (x86)\Microsoft SQL Server\100\DTS\Binn\dtexec.exe" /Rep E /Sql Package /SET \Package.Variables[User::ImportFileName].Value;c:\foo.xlsx'
print @cmd
exec xp_cmdshell @cmd
这很好,但是我不能保证变量值(c:\foo.xslx)不包含空格,所以我想用下面的引号转义:

set @cmd = '"C:\Program Files (x86)\Microsoft SQL Server\100\DTS\Binn\dtexec.exe" /Rep E /Sql Package /SET \Package.Variables[User::ImportFileName].Value;"c:\foo.xlsx"'
但通过这样做,我得到了错误

'C:\Program' is not recognized as an internal or external command, operable program or batch file.

如果在cmd.exe中执行,上述两个命令都可以正常工作,因此我猜测SQL Server正在解释我的双引号并更改某些内容,但我不知道是什么原因。

仔细研究后,您似乎必须将DOS 8.3表示法与xp\u cmdshell一起使用,例如c:\progra~1。。。在参数上只能有一组引号

要绕过此限制,可以使用较旧的DOS表示法,或者将代码放在批处理文件中,这样可以正常运行


来源:

简而言之,将
CMD/S/C“
放在开头,将
放在结尾。在这两者之间,你可以随意引用

以下是您的操作方法:

declare @cmd varchar(8000)
-- Note you can use CMD builtins and output redirection etc with this technique, 
-- as we are going to pass the whole thing to CMD to execute
set @cmd = 'echo "Test" > "c:\my log directory\logfile.txt" 2> "c:\my other directory\err.log" '


declare @retVal int
declare @output table(
    ix int identity primary key,
    txt varchar(max)
)


-- Magic goes here:
set @cmd = 'CMD /S /C " ' + @cmd + ' " '

insert into @output(txt)
exec @retVal = xp_cmdshell @cmd
insert @output(txt) select '(Exit Code: ' + cast(@retVal as varchar(10))+')'

select * from @output