使用 GO 批处理分隔符执行 SQL 脚本并读取结果
Posted
技术标签:
【中文标题】使用 GO 批处理分隔符执行 SQL 脚本并读取结果【英文标题】:Execute SQL Script with GO Batch Separators and Read Results 【发布时间】:2015-11-03 16:21:39 【问题描述】:我有一个带有 GO
批处理分隔符的 SQL 脚本,我试图从 C# 代码中执行该脚本。当我使用Microsoft.SqlServer.Management.Common.ServerConnection.ExecuteNonQuery
时,效果很好。不过,它在 Microsoft.SqlServer.Management.Common.ServerConnection.ExecuteReader
或 Microsoft.SqlServer.Management.Common.ServerConnection.ExecuteWithResults
上爆炸了。
System.AggregateException: One or more errors occurred. --->
Microsoft.SqlServer.Management.Common.ExecutionFailureException: An exception occurred while executing a Transact-SQL statement or batch. --->
System.Data.SqlClient.SqlException: Incorrect syntax near 'GO'.
这是一个非常简单的脚本,如下所示:
SELECT
DB_NAME()
AS
'Database Name';
GO
EXEC [schema].[MyStoredProcedure];
GO
SELECT
[Column]
AS
'Friendly Column Name'
FROM
[schema].[Table];
GO
我尝试了script.Replace("\n", "\r\n")
,得到了相同的结果。有谁知道我如何执行这样的脚本并返回结果?
【问题讨论】:
GO 不是一个实际的 SQL 语句。它是一些 sql 实用程序使用的批处理分隔符。见here。所以基本上 GO 不是有效的 SQL。您应该将所有这些查询、存储过程调用放在一个存储过程中 感谢您的回复,@DustinHodges!请参阅John Galloway's blog post entitled "Handling "GO" Separators in SQL Scripts - the easy way" 了解更多关于 SMO 库如何帮助混淆您描述的问题。 查看了该回复。关键是他正在使用不返回任何结果的 ExecuteNonQuery。正如您在问题中看到的那样,ExecuteNonQuery 可以使用批处理分隔符,但是如果您想返回结果,那么批处理分隔符就不走运了 我不确定这是否正确。你见过the Microsoft Connect feedback page entitled "Error when using ExecuteWithResults SMO Database Object Method"吗? 解决方法是创建多个脚本并单独执行它们,或者类似这个 ps 示例,在 GO 上拆分字符串。 robinosborne.co.uk/2014/10/13/… 字符串拆分有点农业。使用 GO 的主要原因是如果你有 DDL 语句,并且你真的不想要这些结果,因此 ExecuteNonQuery 工作。我认为 ExecuteWithResults 不适用于 GO 的主要原因是因为返回的数据集是不可预测的,因此不能期望 c# 处理所有情况。 【参考方案1】:ExecuteReader 和 ExecuteWithResults 无法识别批处理分隔符 GO。最简单的做法就是删除脚本中的 GO 并调用 ExecuteWithResults
脚本
SELECT
DB_NAME()
AS
'Database Name';
EXEC [schema].[MyStoredProcedure];
SELECT
[Column]
AS
'Friendly Column Name'
FROM
[schema].[Table];
代码
DataSet ds = Database.ExecuteWithResults(script);
DataTable dbNameTable = ds.Tables[0]; //Select DB_NAME()
DataTable storedProcedureResults = ds.Tables[1]; //Exec [schema].[MyStoredProcedure]
DataTable queryResults = ds.Tables[2]; //Select [Column] From [Schema].[Table]
【讨论】:
根据this Microsoft Connect feedback page,Microsoft.SqlServer.Management.Smo.Database.ExecuteWithResults
方法应该可以识别GO
批处理分隔符,但是,我仍然无法让它工作。
首先,这个问题是从 2006 年开始的,几乎没有任何讨论,错误说他只有在使用 nolock 时才会得到错误。其次,我认为它不适用,因为只返回一个数据表。第三,您在评论中链接到您的问题的文章明确指出,批处理分隔符仅适用于您的结果显示的 ExecuteNonQuery。由于我不清楚的原因,您似乎非常希望将非 SQL GO 批处理分隔符保留在 SQL 查询中。你试过我的解决方案了吗?没用吗?
该问题表明应处理GO
批处理分隔符。事实上,BatchSeparator
属性 is well documented。我不确定为什么数据表的数量会影响示例。我不确定您是否阅读了 Galloway 博客文章中的 cmets,但其中一篇特别指出 ExecuteWithResults
应该可以工作。当您说“解决方案”时,您指的是上面的答案吗?这不是我的问题“使用 GO 批处理分隔符和读取结果执行 SQL 脚本”的解决方案。
我猜对你没有帮助。您得到的错误很清楚,GO 附近的语法不正确。您向财产提供文档,但没有说明应该如何在此处应用。您引用了 9 年前的一篇文章,并附有评论说它应该可以工作。但是,唯一提到 ExecuteWithResults 并没有说它可以与批处理分隔符一起使用,只是说 ExecuteImmediate “似乎有效”。祝你好运,但你可以为自己节省一大堆时间,只需移除 GO 并继续你的生活。以上是关于使用 GO 批处理分隔符执行 SQL 脚本并读取结果的主要内容,如果未能解决你的问题,请参考以下文章