使用带有'GO'语句的sp_EXECUTESQL失败来管理数据库中的SQL执行

时间:2011-04-04 12:18:40

标签: sql sql-server-2005 tsql transactions

我有一个应用程序,它将管理DDL更改和TSql Executable语句的发布到SQL服务器数据库。

基本工作流程:开发人员提交.sql文件,收集文件,检查SQL并在发布周期中分配一个步骤,使用存储过程在数据库中执行发布,它将循环执行单个SQL中的步骤使用sp_EXECUTESQL的SQL事务。如果发生任何错误,则事务不会提交DDL更改。此过程将SQL从单个数据库管理到同一实例上的多个数据库。

我遇到的问题是,当提交SQL脚本时,它们包含sp_EXECUTESQL不支持的“GO”语句,并抛出“GO'附近的语法不正确”错误。我可以通过解析'GO'关键字来拆分和拆分大多数事务,但这不适用于其他数据库中的项目。一旦我对另一个数据库有某种ALTER,我需要'GO'。例如以下不得一起执行,不能拆分并作为两个语句执行:

USE [MyDatabaseOtherThanOneIAmExecutingFrom]
GO
Alter PROCEDURE [dbo].[DoSomething]
...

从语法上讲,以下语句不起作用,因此请求开发人员将其sql更改为带有db名称的前缀只会覆盖非DDL SQL:

 Alter PROCEDURE [MyDatabaseOtherThanOneIAmExecutingFrom].[dbo].[DoSomething]

原始要求是保留在数据库中以执行这些部署操作,因此编写一个简短的应用程序以使用SqlCommand从.Net执行批处理不是一种选择。

是否有另一个选项可以在数据库中处理这个问题,还是需要扩展到外部并创建一个应用程序来管理SQL步骤执行?

3 个答案:

答案 0 :(得分:3)

您可以嵌套sp_executesql调用。它有点难看,但它有效,并允许您对其他数据库执行DDL:

sp_executesql N'use OtherDB exec sp_executesql N''create procedure DoStuff @Parm1 varchar(10) as select * from sysobjects'''

答案 1 :(得分:0)

只要你能用自己的话说split and break up most transactions by parsing on the 'GO' keyword,我就看不出问题了。

只需这样做,并使用相同的连接顺序发出GO之间的语句组,即在批次中,而不会中断后者。这本质上是SSMS,以及sqlcmd.exe和osql.exe如何解释'GO'(原谅双关语)。

答案 2 :(得分:0)

首先,您最简单的解决方案是强制拆分GO并尝试使sql文件符合该标准。除此之外,您可以创建一个SSIS包,将文件路径传递给Execute SQL任务并以这种方式执行。如果这对您不起作用,那么您的最后一个解决方案是使用SQL Server管理对象,它允许您将整个脚本一起发送到服务器。要使用SMO,您需要构建一个像C#或VB.NET这样的小应用程序来处理文件并将脚本传递给SMO。

Feature Pack for Microsoft SQL Server 2005 - November 2005

(向下滚动到Microsoft SQL Server 2005管理对象集合)