Как я могу отформатировать свою строку в SQL, чтобы она правильно интерпретировалась в Powershell?

В настоящее время я работаю над простым SQL-скриптом, который хочу запустить из SSMS. Предполагается, что сценарий должен взять базу данных, сделать ее резервную копию, а затем создать ZIP-файл этой резервной копии.

Проблема, с которой я сталкиваюсь, заключается в попытке заархивировать резервную копию. Я объявил все свои переменные в начале файла и считаю, что когда я пытаюсь выполнить @sqlcmd, строка не читается Powershell должным образом.

    SET @sqlcmd = ('powershell.exe [IO.Compression.ZipFile]::CreateFromDirectory("' + @bkpath + '", "C:\'+ @fileName + '.zip")')
    PRINT @sqlcmd 
    -- this statement returns (powershell.exe [IO.Compression.ZipFile]::CreateFromDirectory("C:\Backup\", "C:\ScriptingTestDB_20170607.zip"))
    EXEC xp_cmdshell @sqlcmd   

Запуск этого кода возвращает следующий вывод в моем окне результатов:

At line:1 char:47
+ [IO.Compression.ZipFile]::CreateFromDirectory(C:\Backup", C:\Scriptin ...
+                                               ~
Missing ')' in method call.
At line:1 char:56
+ ... le]::CreateFromDirectory(C:\Backup", C:\ScriptingTestDB_20170607.zip)
+                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The string is missing the terminator: ".
At line:1 char:47
+ ... le]::CreateFromDirectory(C:\Backup", C:\ScriptingTestDB_20170607.zip)
+                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unexpected token 'C:\Backup", C:\ScriptingTestDB_20170607.zip)' in expression or statement.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : MissingEndParenthesisInMethodCall
NULL

После некоторого тестирования я понял, что проблема заключается в том, как Powershell интерпретирует строку SQL. Из-за множества кавычек возможно, что даже если SQL выводит строку правильно, когда Powershell получает ее, формат искажается, поэтому что-то нужно изменить, но все еще не уверен, что. Кто-нибудь знает какие-либо рекомендации, которые я могу использовать, чтобы узнать, как должен быть написан код SQL, чтобы Powershell читал следующее:

[IO.Compression.ZipFile]::CreateFromDirectory("C:\Backup\", "C:\ScriptingTestDB_20170607.zip")

person user2560035    schedule 07.06.2017    source источник
comment
xp_cmdshell — это командная строка, она берет первую кавычку, весь код, который должен попасть в PowerShell, должен быть экранирован интерпретатором cmd. Вам нужно, чтобы это было `powershell [io..]::('c:\...', '...')``, где сценарий PS указан для интерпретатора cmd, а пути указаны в одинарных кавычках, поэтому они не нарушают двойные кавычки. Поэтому избегайте одинарных кавычек в строке SQL. Затем исправьте способ, которым ваш Add-Type не будет переноситься из одного процесса в другой. Вот почему powershell.exe принимает команду в кодировке BASE64, кстати.   -  person TessellatingHeckler    schedule 08.06.2017


Ответы (1)


Вам нужно экранировать " символов с помощью \. Мой рабочий скрипт:

declare @sqlcmd varchar(1000), @bkpath nvarchar(max) = 'C:\i1\tmp', @filename nvarchar(max) = 'file'

SET @sqlcmd = 'powershell.exe Add-Type -AssemblyName System.IO.Compression.FileSystem; [System.IO.Compression.ZipFile]::CreateFromDirectory(\"' + @bkpath + '\", \"C:\i1\'+ @fileName + '.zip\")'
EXEC xp_cmdshell @sqlcmd   
person shibormot    schedule 07.06.2017