2010-09-21 32 views
3

我打電話SSIS包遠程使用存儲的過程和調用的xp_cmdshell:逃逸命令參數對xp_cmdshell到DTEXEC

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正在解釋我的雙引號和更改某些內容,但我無法弄清楚是什麼。

回答

3

簡而言之,把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