2013-01-09 31 views
4

我试图从C#Windows应用程序对数据库执行脚本(.sql文件)。 SQL文件包含'GO'语句;这意味着我正在使用对象SMO。从C#执行SQL脚本并记录错误

我想继续错误日志的任何错误可能脚本的数据库上执行过程中发生的。有没有办法做到这一点?

这是我使用的代码:

using (SqlConnection sqlConnection = new SqlConnection(connectionString)) 
{ 
    ServerConnection svrConnection = new ServerConnection(sqlConnection); 
    Server server = new Server(svrConnection); 

    string script = File.ReadAllText("upgradeDatabase.sql"); 

    try 
    { 
     server.ConnectionContext.ExecuteNonQuery(script, ExecutionTypes.ContinueOnError); 
    } 
    catch (Exception ex) 
    { 
     //handling and logging for the errors are done here 
    } 
} 

任何帮助表示赞赏!

回答

4

我想你这里有两个问题:

首先,你调用接受一个字符串ExecuteNonQuery方法,而不是一个StringCollection。我想这种方法不能识别用于分离批处理语句的GO。相反,接受StringCollection的方法ExecuteNonQuery的文档声明GOes已识别

第二个问题是ExecutionTypes.ContinueOnError通过。在这种情况下,相同的文档指出,如果出现问题,您将无法收到异常。

我认为最好的方法应该是在GO中拆分输入文本,然后构建一个StringCollection以传递给ExecuteNonQuery方法并检查返回的受影响行的数组。 像这样(应进行测试)

using (SqlConnection sqlConnection = new SqlConnection(connectionString)) 
{ 
    ServerConnection svrConnection = new ServerConnection(sqlConnection); 
    Server server = new Server(svrConnection); 

    string script = File.ReadAllText("upgradeDatabase.sql"); 
    string[] singleCommand = Regex.Split(script, "^GO", RegexOptions.Multiline); 
    StringCollection scl = new StringCollection(); 
    foreach(string t in singleCommand) 
    { 
     if(t.Trim().Length > 0) scl.Add(t.Trim()); 
    } 
    try 
    { 
     int[] result = server.ConnectionContext.ExecuteNonQuery(scl, ExecutionTypes.ContinueOnError); 
     // Now check the result array to find any possible errors?? 
    } 
    catch (Exception ex) 
    { 
     //handling and logging for the errors are done here 
    } 
} 

当然另一种方法是在执行每个单个语句并取出ContinueOnError标志。然后捕获并记录可能的例外情况。但是这肯定会变慢。

+0

在文本中与** GO **分离可能会破坏脚本,想象一下你必须选择CATE ** GO ** RY FROM WHATEVER –

+1

您是否注意到我使用将GO固定到行首的正则表达式模式? http://msdn.microsoft.com/en-US/library/az24scfc(v=vs.90) – Steve

+0

谢谢史蒂夫你的解决方法。我正在执行每条单一语句,并在发生时捕获任何错误。 – naregkar

0

可以使用smo库,where是如何添加到项目

FileInfo file = new FileInfo("upgradeDatabase.sql"); 
string script = file.OpenText().ReadToEnd(); 
SqlConnection conn = new SqlConnection(sqlConnectionString); 
Server server = new Server(new ServerConnection(conn)); 
server.ConnectionContext.ExecuteNonQuery(script); 
+0

downvoter请发表评论 –

+0

随着你的回答,脚本将停止执行第一个错误。我希望OP是毕竟的错误。(不downvoter) –

+0

啊,右@DavidWhite,感谢您的更正 –

0

我真的很喜欢这个变体,它使用InfoMessage事件和处理程序:

 using(SqlConnection sc = new SqlConnection(connStr)) 
     { 
      sc.InfoMessage += new SqlInfoMessageEventHandler(sc_InfoMessage); 
      Server db = new Server(new ServerConnection(sc)); 
      db.ConnectionContext.ExecuteNonQuery(commandFileText, ExecutionTypes.ContinueOnError); 
     } 

您将需要添加一个参考以下内容:

  • Microsoft.SqlServer.ConnectionInfo.dll
  • Microsoft.SqlServer.Management.Sdk.Sfc.dll
  • Microsoft.SqlServer.Smo.dll
  • Microsoft.SqlServer.SqlEnum.dll
0

我不是程序员(DBA),因此我不确定。 我认为以下内容可能有帮助

svrConnection.FireInfoMessageEventOnUserErrors = true;