2011-04-06 51 views
3

我有这个使用BCP从表转储数据的TSQL代码。它看起来很复杂,但它只是创建一个@command字符串,为每个表执行一次,然后BCP将表记录转储到磁盘。这是快速备份所有表格数据的好方法。下面我展示了一个更容易阅读的解决版本。Microsoft SQL xp_cmdshell不喜欢带空格的文件名。我可以用其他东西替换空间吗?

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 

@bcppath的是C:\Program Files\Microsoft SQL Server\90\Tools\Binn\bcp.exe具有空间。

不使用双引号围绕路径"",它给出了一个错误'C:\Program' is not recognized...使用双引号引起相同的错误。对于使用双双引号"" "",它说,打印时The filename, directory name, or volume label syntax is incorrect.

@command解析到此:

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; 

编辑:

奇怪的是,我在“路径”的前面放一个ECHO ? &&和它工作(由双引号包围)....为什么?

+0

是不是路径中的.. \ binn目录? – DaveE 2011-04-06 15:40:17

+0

即使是这样,第二条路也会杀死它。 – 2011-04-06 16:24:27

+1

可能。如果xp_cmdshell在没有路径组件的情况下调用bcp“bcp myDB.dbo ...”,会发生什么情况?我问b/c我们使用bcp进行批量加载,它不关心文件路径在我们的本地或客户端安装中是否有空格。 – DaveE 2011-04-06 16:43:22

回答

5

你必须把东西引述前路径,以避免C:\Program' is not recognized...所以我用CALL语句错误和它的工作对我来说...

declare @cmd nvarchar(1000) 

set @cmd = 'call "C:\Program Files\Microsoft SQL Server\90\Tools\Binn\bcp.exe" myDB.dbo.' 
exec xp_cmdshell @cmd 
4

尝试指定包含空格的路径部分的短名称例如,PROGRA〜1而不是程序文件。因此,您的第一个路径将是类似于C:\ PROGRA〜1 \ MI6841〜1 \ 90 \ Tools \ Binn \ bcp.exe。如果你没有空格,你应该可以删除引号。

如果您在包含长目录/文件名的目录中执行dir /x,则可以获取简短的8.3名称。

+0

+1,但它取决于当前系统,在下一个系统中短名称可以不同 – jeb 2011-04-06 19:22:36

+0

然而,绝对的(有趣的是)一位同事在他的机器上检查了这个,短名称是相同的。我原以为他们必须有所不同,特别是* Microsoft SQL Server => MI6841〜1 *,因为我们有非常不同的软件安装。 – arcain 2011-04-06 19:27:12

+0

我想这只取决于安装顺序,因为短名称在创建时刻(也是长名称) – jeb 2011-04-06 19:33:02

1

作为解决方法,您可以使用subst

subst p: "C:\Program Files\Microsoft SQL Server\" 

所以你不需要间隔的路径了。

或者你试图找出失败的原因。

exec xp_cmdshell 'cmd /c echo %cmdcmdline% "C:\Program Files\Microsoft SQL Server\90\Tools\Binn\bcp.exe"' 

的CMDCMDLINE应该表现出你完整的命令,如果报价已经存在这应该工作

exec xp_cmdshell 'cmd /c "C:\Program Files\Microsoft SQL Server\90\Tools\Binn\bcp.exe" <the rest of your command>' 
+0

神奇的想法。 – 2011-04-13 21:42:52

0

这个奇怪的建筑也在努力:

exec xp_cmdshell '""%ProgramFiles%\WinRAR\"rar.exe a -v20M "C:\test\test.rar" "C:\test\data\""' 
相关问题