Microsoft SQL xp_cmdshell не любит имена файлов с пробелами. Могу ли я заменить пространство на что-то еще? - PullRequest
3 голосов
/ 06 апреля 2011

У меня есть этот код TSQL, который выводит данные из таблиц, используя BCP. Это выглядит сложно, но просто создает строку @command, которая будет выполняться один раз для каждой таблицы, а затем BCP выдает записи таблицы на диск. Это хороший способ быстро сделать резервную копию всех данных таблицы. Ниже я показываю исправленную версию, которую немного легче читать.

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.

@ команда разрешает это при печати:

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:

Как ни странно, я поставил ECHO ? && перед "путем", и он сработал (окруженный двойными кавычками) .... Почему?

Ответы [ 4 ]

7 голосов
/ 22 января 2016

Вы должны поместить что-то перед указанным путем, чтобы избежать ошибки 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
5 голосов
/ 06 апреля 2011

Попробуйте указать короткое имя для частей пути, содержащих пробелы. Например, PROGRA ~ 1 вместо Program Files .Итак, ваш первый путь будет выглядеть примерно так: C: \ PROGRA ~ 1 \ MI6841 ~ 1 \ 90 \ Tools \ Binn \ bcp.exe .Если у вас нет пробелов, вы сможете удалить кавычки.

Если вы выполните dir /x в каталоге, содержащем длинные имена каталогов / файлов, вы можете получить короткое имя 8.3.

1 голос
/ 06 апреля 2011

В качестве обходного пути вы можете использовать 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 голосов
/ 14 ноября 2017

Эта странная конструкция тоже работает:

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