Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从transaction.Commit()检索SQL错误消息_C#_Transactions_Rollback_Sqlcommand - Fatal编程技术网

C# 从transaction.Commit()检索SQL错误消息

C# 从transaction.Commit()检索SQL错误消息,c#,transactions,rollback,sqlcommand,C#,Transactions,Rollback,Sqlcommand,我有一段代码,它遍历SQL命令列表,这些命令应该作为一个事务的一部分进行处理。我想知道该事务是否成功用于错误记录和处理目的。此时此刻,由于某种原因,我很难看到任何类型的实际异常或不成功的提交。我现在正在使用下面的代码。尝试捕获来自MSDN页面推荐。请随意在这上面戳出任何你能看到的不是100%关于我的问题的漏洞。这些都是存储过程类型的SqlCommands的命令,在将其添加到SQL命令列表之前,已将参数添加到其中 public static async Task UpdateSQL(string

我有一段代码,它遍历SQL命令列表,这些命令应该作为一个事务的一部分进行处理。我想知道该事务是否成功用于错误记录和处理目的。此时此刻,由于某种原因,我很难看到任何类型的实际异常或不成功的提交。我现在正在使用下面的代码。尝试捕获来自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();
            }
        }
    }
}
公共静态异步任务更新SQL(字符串输入查询, 字符串输入、列表命令列表、TraceWriter日志) { 尝试 { string str=ConfigurationManager.ConnectionString [“连接字符串”]。连接字符串; log.Info($“正在运行的查询:{inputQuery}”); int命令行=0; 使用(SqlConnection conn=newsqlconnection(str)) { conn.Open(); SqlTransaction tr=conn.BeginTransaction(); 尝试 { SqlCommand cmd=新的SqlCommand(inputQuery,conn); cmd.Transaction=tr; foreach(commandList中的var命令) { command.Connection=conn; command.Transaction=tr; log.Info($“{command.CommandText}正在运行的查询”);//如果失败,最后一次日志输出(基于数据库中的最终结果) commandRows+=等待命令。ExecuteOnQueryAsync(); } Info($“更新的行总数:{commandRows}”); tr.Commit(); 康涅狄格州关闭(); } 捕获(例外情况除外) { WriteLine($“提交异常类型:{ex.GetType()}”); WriteLine($“Message:{ex.Message}”); 尝试 { tr.Rollback(); 康涅狄格州关闭(); log.Info($“{inputId}事务回滚”); } 捕获(异常ex2) { //回滚失败异常 Info($“回滚异常类型:{ex2.GetType()}”); log.Info($“Message:{ex2.Message}”); 康涅狄格州关闭(); } } } }
尝试捕获SqlException

然后这样做:

StringBuilder sqlErrorMessages=新建StringBuilder(“Sql异常:\n”)

如果错误的严重性为16或更高,则只有在C#中才会出现异常。如果使用打印,则在.NET中不会出现异常

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

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


只是一个旁注-如果不直接返回,SQL Server将在RAISERROR之后继续运行命令。如果不返回,则可以返回多个错误。

无需执行显式的
conn.Close()
(以及其中的一个)-使用块可以做到这一点。
由于某种原因,我现在很难看到任何类型的实际异常或不成功的提交。
这一点不清楚。你是说它总是有效的,你希望它不起作用,这样你就可以看到发生了什么?或者其他事情了?@mjwillis很棒。为了以防万一,添加了它。因此只要使用using语句,e就不需要在这段代码中的任何地方连接.Close()?那太好了。大多数情况下,它都是成功的,但通过调试,如果一组命令不成功,它似乎只会打印log.Info($“{command.CommandText}query running”);日志的一部分,它似乎从未真正到达Console.WriteLine($“提交异常类型:{ex.GetType()}”);Console.WriteLine($“消息:{ex.Message}”);部分
,因此不需要连接.Close()这段代码中的任何地方都可以使用using语句吗?
Yes。如果收到SqlCommand列表,cmd=new SqlCommand(inputQuery)行的用途是什么?
    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));

    }