执行大型SQL脚本(使用GO命令)
我需要从C程序中执行大量SQL语句集(创建一堆表,视图和存储过程)。
这些语句需要用GO
语句分隔,但是SqlCommand.ExecuteNonQuery()
不喜欢GO
语句。我想提供参考的解决方案是在" GO"行上分割SQL字符串,并分别执行每个批处理。
有没有更简单/更好的方法?
解决方案
回答
我也遇到了同样的问题,除了将单个SQL操作拆分为单独的文件,然后依次执行所有其他操作外,我找不到其他任何方法。
显然问题不在于DML命令列表,它们之间可以在没有GO的情况下执行;使用DDL的不同故事(创建,更改,删除...)
回答
这就是我共同解决当前问题的方法。
private void ExecuteBatchNonQuery(string sql, SqlConnection conn) { string sqlBatch = string.Empty; SqlCommand cmd = new SqlCommand(string.Empty, conn); conn.Open(); sql += "\nGO"; // make sure last batch is executed. try { foreach (string line in sql.Split(new string[2] { "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries)) { if (line.ToUpperInvariant().Trim() == "GO") { cmd.CommandText = sqlBatch; cmd.ExecuteNonQuery(); sqlBatch = string.Empty; } else { sqlBatch += line + "\n"; } } } finally { conn.Close(); } }
它要求GO命令位于其自己的行上,并且不会检测到块注释,因此这类事情将被拆分,并导致错误:
ExecuteBatchNonQuery(@" /* GO */", conn);
回答
使用了解GO分隔符的SQL Server管理对象(SMO)。在这里查看我的博客文章:http://weblogs.asp.net/jongalloway/Handling-2200_GO_2200-Separators-in-SQL-Scripts-2D00-the-easy-way
样例代码:
public static void Main() { string scriptDirectory = "c:\temp\sqltest\"; string sqlConnectionString = "Integrated Security=SSPI;" + "Persist Security Info=True;Initial Catalog=Northwind;Data Source=(local)"; DirectoryInfo di = new DirectoryInfo(scriptDirectory); FileInfo[] rgFiles = di.GetFiles("*.sql"); foreach (FileInfo fi in rgFiles) { FileInfo fileInfo = new FileInfo(fi.FullName); string script = fileInfo.OpenText().ReadToEnd(); using (SqlConnection connection = new SqlConnection(sqlConnectionString)) { Server server = new Server(new ServerConnection(connection)); server.ConnectionContext.ExecuteNonQuery(script); } } }
如果这对我们不起作用,请参阅Phil Haack的库来处理该问题:http://haacked.com/archive/2007/11/04/a-library-for-executing-sql-scripts-with-go-separators -和.aspx
回答
我们可以使用SQL管理对象来执行此操作。这些是Management Studio用于执行查询的对象。我相信Server.ConnectionContext.ExecuteNonQuery()
会执行我们需要的操作。
回答
SQL Management Studio本身实际上使用了" GO"批处理分隔符关键字,因此它知道终止发送到服务器的批处理的位置,并且不会传递给SQL Server。如果需要,我们甚至可以在Management Studio中更改关键字。
回答
如果我们不想走SMO路线,则可以搜索并将" GO"替换为";"和查询一样。请注意,将最后一个结果集返回。