SQLCMD模式下的ServerConnection.ExecuteNonQuery

我正在使用Microsoft Data-Tier Application框架来创建基于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生成的脚本。 谁能帮我这个?

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 Server数据工具(SSDT)/ Visual Studio生成的部署SQL脚本需要通过这三个程序之一运行。

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

  • SqlPackage.exeMSDeploy.exe 。 它们都在使用命令行工具的面向项目的数据库开发的MSDN页面上进行了描述。
  • DacServices.Deploy() 。 这可以通过DacServices类在C#中完成。

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

 USE [$(DatabaseName)]; 

虽然可以通过将CommentOutSetVarDeclarations的DacDeployOptions属性设置为true来注释掉initial :setvar行,但仍会保留: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是通过对象而不是直接通过T-SQL命令与SQL Server交互的手段。

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

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

  • C#通过Process.Start调用SQLCMD.EXE -i filename.sql : http : //msdn.microsoft.com/en-us/library/system.diagnostics.process.start( SQLCMD.EXE -i filename.sql .aspx
  • C#通过开源库来处理“GO”语句和SQLCMD模式冒号命令(当前处理SQL文件,但可以很容易地更新以接受字符串): https : //github.com/rusanu/DbUtilSqlCmd
  • PowerShell通过Invoke-SqlCMD: http ://www.sqlservercentral.com/Forums/Topic1502697-1351-1.aspx