6

Я использую Microsoft Data-Tier Application framework для создания сценария развертывания на основе объекта DacPackage. Я пытаюсь использовать Microsoft.SqlServer.Management.Smo.Server класс для выполнения этого сценария ...ServerConnection.ExecuteNonQuery в режиме SQLCMD

SqlConnection deployConnection = new SqlConnection(connBuilder.ToString()); 
deployConnection.Open(); 
Server server = new Server(new ServerConnection(deployConnection)); 
server.ConnectionContext.ExecuteNonQuery(deployScript); 

Однако эти ошибки с ...

Unhandled Exception: Microsoft.SqlServer.Management.Common.ExecutionFailureException: 
    An exception occurred while executing a Transact-SQL statement or batch. ---> 
    System.Data.SqlClient.SqlException: Incorrect syntax near ':'. 

Я знаю, что ответ на этот вопрос в том, что мне нужно быть в режиме SQLCMD, но я не знаю, как сообщить моему ServerConnection для выполнения в указанном режиме.

Я думаю, что моя проблема не такая конкретная, как то, что я заявляю в названии. То, что мне действительно нужно, это выполнить скрипт, созданный из DacPackage через .Net framework. Кто-нибудь может мне с этим помочь?

ответ

9

Команды режима SQLCMD: не Команды T-SQL; они работают только в SQL Server Management Studio (SSMS)/Visual Studio (VS) и SQLCMD.EXE. SQLCMD-режим по сути является тем, как работает SQLCMD.EXE и может быть включен вручную в SSMS/VS; это часть этих приложений, а не то, что может быть сделано через поставщика.

Эти приложения интерпретируют команды режима SQLCMD и не передают их SQL Server. Команды SQLCMD-режима сначала разбираются/выполняются (именно так они могут влиять на SQL, который должен быть отправлен), а затем окончательная версия SQL отправляется на SQL Server.

Следовательно, сценарии развертывания SQL, сгенерированные SQL Server Data Tools (SSDT) ​​/ Visual Studio, должны запускаться через одну из этих трех программ.

Поскольку у вас есть .dacpac файл уже, Microsoft предоставляет несколько способов для публикации тех, которые вы должны проверить:

Вы также можете создать публикацию SQL скрипт через DacServices.GenerateDeployScript(), но это не изменит ситуацию, как указано выше, так как публикация/развернуть SQL сценарий, будь то генерируется из Visual Studio «Опубликовать {PROJECT_NAME}» или GenerateDeployScript(), это тот же сценарий. Значение, он будет иметь SQLCMD режима толстой кишки-команды, такие как :setvar и :on error exit, а также переменных SQLCMD режима, который, по крайней мере, будет $(DatabaseName), который используется в следующей строке:

USE [$(DatabaseName)]; 

While можно запрограммировать начальные строки :setvar, установив свойство DacDeployOptionsCommentOutSetVarDeclarations на true, которое все равно оставит линию :on error exit, а также линию для :setvar __IsSqlCmdEnabled "True", которая используется для определения того, включен ли режим SQLCMD. Над этой конкретной :setvar строки является комментарием с указанием:

/* 
Detect SQLCMD mode and disable script execution if SQLCMD mode is not supported. 
To re-enable the script after enabling SQLCMD mode, execute the following: 
SET NOEXEC OFF; 
*/ 

Так что они действительно намерены, что этот скрипт запускается только через SQLCMD, будь то через DOS -> Sqlcmd.exe или PowerShell -> Invoke-Sqlcmd.

Технически можно создать строку содержимого сценария развертывания (а не stream) и манипулировать этой строкой: a) удалением любых команд двоеточия и b) заменой «$ (DatabaseName)» на любое которую вы планируете использовать. Тем не менее, я не пробовал этого, я не рекомендую это, и я не уверен, что он будет работать во всех ситуациях, какие сценарии развертывания могут быть созданы с помощью SQL Server Data Tools. Но это похоже на вариант.

Кроме того, незначительно связано: вам не нужно SMO для запуска SQL-скриптов. SMO - это средство взаимодействия с SQL Server через объекты, а не напрямую через команды T-SQL.

EDIT:
ссылки, где другие пытались это и нашел, что это не сработало:

Возможности для получения сгенерированного публикации SQL скрипт для работы программные:

+0

Так что нет * нет * способ программно выполнить сгенерированные Sqlcmd сценарии из рамок .Net - это то, что вы говорите? –

+3

@ DanForbes - в значительной степени, да. Ничто из этих трех программ не знает, что такое команды двоеточия. НО, это не значит, что вы не можете запустить процесс на C# для вызова командной строки для «SQLCMD.EXE -S-сервера» и указать имя сценария и соответствующий флаг для передачи в SQL-скрипте. –

+1

Большое спасибо, @srutzky! –