12

我正在使用Microsoft 数据层应用程序框架来创建基于DacPackage对象的部署脚本。我正在尝试使用Microsoft.SqlServer.Management.Smo.Server类来执行此脚本...

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在所述模式下执行。

我想我的问题并不像我在标题中所说的那样具体。我真正需要做的是通过 .Net 框架执行从 DacPackage 生成的脚本。谁能帮我这个?

4

1 回答 1

16

SQLCMD 模式命令不是T-SQL 命令;它们仅适用于 SQL Server Management Studio (SSMS) / Visual Studio (VS) 和 SQLCMD.EXE。SQLCMD-mode 本质上是 SQLCMD.EXE 的工作方式,可以在 SSMS / VS 中手动启用;它是这些应用程序的一部分,而不是可以通过提供商完成的事情。

这些应用程序解释 SQLCMD 模式命令并且不将它们传递给 SQL Server。SQLCMD 模式命令首先被解析/执行(这是它们能够影响即将提交的 SQL 的方式),然后将 SQL 的最终版本提交给 SQL Server。

因此,由 SQL Server Data Tools (SSDT) / Visual Studio 生成的部署 SQL 脚本需要通过这三个程序之一运行。

由于您已经有一个.dacpac文件,Microsoft 提供了几种方法来发布您应该检查的文件:

您还可以通过DacServices.GenerateDeployScript()创建发布 SQL 脚本,但这不会改变上述情况,因为发布/部署 SQL 脚本,无论是从 Visual Studio "Publish {project_name}" 还是 生成GenerateDeployScript(),都是相同的脚本。这意味着,它将具有 SQLCMD 模式冒号命令,例如:setvar:on error exit以及 SQLCMD 模式变量,至少将$(DatabaseName)在以下行中使用:

USE [$(DatabaseName)];

虽然可以通过将 CommentOutSetVarDeclarations 的DacDeployOptions属性设置为来注释掉初始:setvar行,但这仍然会留下该行以及用于检测是否已启用 SQLCMD 模式的行。就在这一特定行的上方是一条评论,说明:true:on error exit:setvar __IsSqlCmdEnabled "True":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。

从技术上讲,可以生成部署脚本内容的字符串(而不是 a stream)并通过以下方式操作该字符串:a)删除任何冒号命令,b)用您打算部署的任何数据库替换“$(DatabaseName)”至。但是,我没有尝试过,我不推荐这样做,并且我不确定它是否适用于 SQL Server Data Tools 可以生成哪些部署脚本的所有情况。但这似乎是一种选择。

此外,次要相关:您不需要 SMO 来运行 SQL 脚本。SMO 是通过对象而不是直接通过 T-SQL 命令与 SQL Server 交互的方法。

编辑:
其他人尝试过并发现它不起作用的链接:

使生成的发布 SQL 脚本以编程方式工作的可能性:

于 2014-10-28T20:07:08.033 回答