I have this TSQL code that dumps data from tables using BCP. It looks complicated, but it simply creates a @command string to be executed once for each table, then BCP dump the table records to disk. It's a nice way to backup all the table data quickly. Below I show the resolved version which is a little easier to read.
set @command =
'if (''?'' <> ''[dbo].[sysdiagrams]'')
BEGIN;
create table #result (result nvarchar(2048) null );
declare @temp nvarchar(1000);
set @temp = ''' + @bcpPath + ' ' + @database + '.dbo.'' +
substring( ''开发者_运维问答?'', 8, len(''?'')- 8) +
'' out "' + @driveLetter + @drivePath +
'\'' + substring( ''?'', 8, len(''?'')- 8) +
''.out" -c -x -t"|" -Uuser -Ppassword'';
insert into #result (result)
exec xp_cmdshell @temp;
drop table #result;
END;'
exec sp_msforeachtable @command
the @bcppath
is C:\Program Files\Microsoft SQL Server\90\Tools\Binn\bcp.exe
which has a space.
Without using double quotes around the path ""
, it gives an error of 'C:\Program' is not recognized...
With using double quotes, it gives the same error. With using double double quotes "" ""
, it says The filename, directory name, or volume label syntax is incorrect.
@command resolves to this when printed:
if ('?' <> '[dbo].[sysdiagrams]')
BEGIN;
create table #result (result nvarchar(2048) null );
declare @temp nvarchar(1000);
set @temp = '"C:\Program Files\Microsoft SQL Server\90\Tools\Binn\bcp.exe"
myDB.dbo.' +
substring( '?', 8, len('?')- 8) +
' out "E:\DataExports\' +
substring( '?', 8, len('?')- 8) + '.out" -c -x -t"|" -Uuser -Ppassword';
insert into #result (result)
exec xp_cmdshell @temp;
drop table #result;
END;
EDIT:
Oddly, I put an ECHO ? &&
in front of the "path" and it worked (surrounded by double quotes.) .... Why?
You have to put something before quoted path to avoid error C:\Program' is not recognized...
so I used CALL statement and it worked for me ...
declare @cmd nvarchar(1000)
set @cmd = 'call "C:\Program Files\Microsoft SQL Server\90\Tools\Binn\bcp.exe" myDB.dbo.'
exec xp_cmdshell @cmd
Try specifying the short name for the parts of the path containing spaces For example, PROGRA~1 rather than Program Files. So, your first path would be something like C:\PROGRA~1\MI6841~1\90\Tools\Binn\bcp.exe. If you don't have any spaces, you should be able to drop the quotes.
If you perform a dir /x
in the directory containing the long directory/file names you can obtain the short 8.3 name.
As workaround, you could use subst
.
subst p: "C:\Program Files\Microsoft SQL Server\"
so you didn't need the spaced path anymore.
Or you try to find out why it fails.
exec xp_cmdshell 'cmd /c echo %cmdcmdline% "C:\Program Files\Microsoft SQL Server\90\Tools\Binn\bcp.exe"'
The cmdcmdline should show you the complete command, if the quotes are already there this should work
exec xp_cmdshell 'cmd /c "C:\Program Files\Microsoft SQL Server\90\Tools\Binn\bcp.exe" <the rest of your command>'
This weird construction also working:
exec xp_cmdshell '""%ProgramFiles%\WinRAR\"rar.exe a -v20M "C:\test\test.rar" "C:\test\data\""'
精彩评论