【问题标题】:Retrieving SQL error message from transaction.Commit()从 transaction.Commit() 中检索 SQL 错误消息
【发布时间】:2018-06-08 22:08:34
【问题描述】:

我有一段代码遍历一个 SQL 命令列表,这些命令应该作为一个事务的一部分进行处理。我想知道该事务是否成功用于错误记录和处理目的。由于某种原因,此时此刻我在看到任何类型的实际异常或不成功的提交时遇到问题。我现在正在使用下面的代码。 try catch 来自 MSDN 页面推荐。请随时戳出任何其他你可以看到的不是 100% 关于我的问题的漏洞。这些都是存储过程类型的 SqlCommands 的所有命令,在将其添加到 SQL 命令列表之前添加了参数。

public static async Task UpdateSQL(string inputQuery, 
    string inputId, List<SqlCommand> commandList, TraceWriter log)
{
    try
    {
        string str = ConfigurationManager.ConnectionStrings
            ["connString"].ConnectionString;

    log.Info($"Running query: {inputQuery}");
    int commandRows = 0;
    using (SqlConnection conn = new SqlConnection(str))
    {
        conn.Open();
        SqlTransaction tr = conn.BeginTransaction();

        try
        {
            SqlCommand cmd = new SqlCommand(inputQuery, conn);
            cmd.Transaction = tr;
            foreach (var command in commandList)
            {
                command.Connection = conn;
                command.Transaction = tr;
                log.Info($"{command.CommandText} query running"); //last log output if unsuccesful (based on end result in database)
                commandRows += await command.ExecuteNonQueryAsync();
            }
            log.Info($"total rows updated: {commandRows}");

            tr.Commit();
            conn.Close();
        }
        catch(Exception ex)
        {
            Console.WriteLine($"Commit Exception Type: {ex.GetType()}");
            Console.WriteLine($"  Message: {ex.Message}");

            try
            {
                tr.Rollback();
                conn.Close();
                log.Info($"{inputId} transaction rolled back");
            }
            catch (Exception ex2)
            {
                // rollback fail Exception
                log.Info($"Rollback Exception Type: {ex2.GetType()}");
                log.Info($"  Message: {ex2.Message}");
                conn.Close();
            }
        }
    }
}

【问题讨论】:

  • 没有必要做明确的conn.Close()(和他们) - using 块会为你做。
  • At this moment in time for some reason I have a problem seeing any kind of actual exception or unsuccessful commit. 这还不清楚。你的意思是它总是有效,而你希望它不会,这样你就可以看到会发生什么?还是别的什么?
  • @mjwill 很棒。添加以防万一。所以只要在这里使用 using 语句,就不需要在这段代码中的任何地方使用 conn.Close() 吗?那很好啊。好吧,大多数时候它是成功的,但通过调试,如果一组命令不成功,它只会打印 log.Info($"{command.CommandText} query running");日志的一部分,它似乎从未真正到达 Console.WriteLine($"Commit Exception Type: {ex.GetType()}"); Console.WriteLine($" Message: {ex.Message}");部分
  • so there is no need to conn.Close() anywhere in this piece of code as long as the using statement is used as it is here? 是的。
  • 如果您收到 SqlCommand 列表,cmd = new SqlCommand(inputQuery) 行的目的是什么?

标签: c# transactions rollback sqlcommand


【解决方案1】:

尝试捕获 SqlException

然后这样做:

StringBuilder sqlErrorMessages = new StringBuilder("Sql Exception:\n");

    foreach (SqlError error in ex.Errors)
    {
        sqlErrorMessages.AppendFormat("Mesage: {0}\n", error.Message)
            .AppendFormat("Severity level: {0}\n", error.Class)
            .AppendFormat("State: {0}\n", error.State)
            .AppendFormat("Number: {0}\n", error.Number)
            .AppendFormat("Procedure: {0}\n", error.Procedure)
            .AppendFormat("Source: {0}\n", error.Source)
            .AppendFormat("LineNumber: {0}\n", error.LineNumber)
            .AppendFormat("Server: {0}\n", error.Server)
            .AppendLine(new string('-',error.Message.Length+7));

    }

如果您的错误的严重性为 16 或更高,您只会在 C# 中获得异常。如果您使用的是 PRINT,则在 .NET 中不会出现异常。

如果您可以编辑 raise 错误代码,这将导致 C# 中的 SqlException:

RAISERROR('一些错误信息', 16, 1) 然后,您可以访问 SqlException.Errors 集合中的每个单独的错误。

附带说明 - 如果您之后不直接返回,SQL Server 将在 RAISERROR 之后继续运行命令。如果不返回,可能会返回多个错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-24
    • 2020-03-24
    • 2011-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多