5

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

我正在尝试继续出错,并记录在数据库上执行脚本期间可能发生的任何错误。有没有办法做到这一点?

这是我正在使用的代码:

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

4 回答 4

4

我认为你在这里有两个问题:

首先,调用接受字符串而不是 StringCollection 的 ExecuteNonQuery 方法。我想这个方法不能识别用于分隔批处理语句的 GO。相反,接受 StringCollection 的ExecuteNonQuery方法的文档指出 GO 已被识别

第二个问题是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标志。然后捕获并记录可能的异常。但这肯定会慢一些。

于 2013-01-09T11:56:12.190 回答
1

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

        using(SqlConnection sc = new SqlConnection(connStr))
        {
            sc.InfoMessage += new SqlInfoMessageEventHandler(sc_InfoMessage);
            sc.FireInfoMessageEventOnUserErrors = true;
            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
于 2016-09-08T05:24:49.617 回答
1

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

svrConnection.FireInfoMessageEventOnUserErrors = true;

于 2017-04-03T09:54:12.087 回答
0

您可以使用smo库,如何添加到项目中

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);
于 2013-01-09T11:43:12.117 回答