C# C读取数据时遇到致命错误

C# C读取数据时遇到致命错误,c#,mysql,datareader,C#,Mysql,Datareader,我从数据库中选择了大约20000条记录,然后逐一更新。 我查找了这个错误,发现设置CommandTimeout会有所帮助,但在我的情况下不会 下面是我的选择查询方法: public void CleanRecords() { SQLActions.Initialize(); SQLActions.SQL_Open(); MySqlDataReader cashData = SQLActions.SQL_Query("SELE

我从数据库中选择了大约20000条记录,然后逐一更新。 我查找了这个错误,发现设置CommandTimeout会有所帮助,但在我的情况下不会

下面是我的选择查询方法:

        public void CleanRecords()
    {
        SQLActions.Initialize();
        SQLActions.SQL_Open();
        MySqlDataReader cashData = SQLActions.SQL_Query("SELECT `cash`.`id`, SUM(`cash`.`income_money`) AS `income_money`, `cash_data`.`total` FROM `cash_data` JOIN `cash` ON `cash`.`cash_data_id` = `cash_data`.`id` WHERE `user`='0' AND `cash_data`.`paymentterm_id`='0' OR `cash_data`.`paymentterm_id`='1' GROUP BY `cash_data_id`");
        while(cashData.Read()){
            if(cashData["income_money"].ToString() == cashData["total"].ToString()){
                UpdateRecords(cashData["id"].ToString());
            }
        }
        SQLActions.SQL_Close();
    }
下面是进行更新的方法:

        public void UpdateRecords(string rowID)
    {
        SQLActions.Initialize();
        SQLActions.SQL_Open();
        SQLActions.SQL_NonQuery("UPDATE `cash_data` SET `end_date`='" + GetMeDate() + "', `user`='1' WHERE `id`='" + rowID + "'");
        SQLActions.SQL_Close();
    }
更改数据库结构不是我的选择。 我认为将超时设置为int的maxvalue可以解决我的问题,但在我的情况下,这似乎不起作用。 有什么想法吗

编辑: 我得到的错误是在数据读取过程中遇到的致命错误

更新:

        public void CleanRecords()
    {
        StringBuilder dataForUpdate = new StringBuilder();
        string delimiter = "";

        SQLActions.Initialize();
        SQLActions.SQL_Open();
        MySqlDataReader cashData = SQLActions.SQL_Query("SELECT `cash`.`id`, SUM(`cash`.`income_money`) AS `income_money`, `cash_data`.`total` FROM `cash_data` JOIN `cash` ON `cash`.`cash_data_id` = `cash_data`.`id` WHERE `user`='0' AND `cash_data`.`paymentterm_id`='0' OR `cash_data`.`paymentterm_id`='1' GROUP BY `cash_data_id`");
        while (cashData.Read())
        {
            if (cashData["income_money"].ToString() == cashData["total"].ToString())
            {
                dataForUpdate.Append(delimiter);
                dataForUpdate.Append("'" + cashData["id"].ToString() + "'");
                delimiter = ",";
            }
        }
        SQLActions.SQL_Close();
        UpdateRecords(dataForUpdate.ToString());
    }

    public void UpdateRecords(string rowID)
    {
        SQLActions.Initialize();
        SQLActions.SQL_Open();
        SQLActions.SQL_NonQuery("UPDATE `cash_data` SET `end_date`='" + GetMeDate() + "', `user`='1' WHERE `id` IN (" + rowID + ")");
        SQLActions.SQL_Close();
    }

存在多个问题:

首先:您可以使用数据读取器读取20K左右的信息,然后在读取器中逐个进行更新。读卡器保持连接打开,直到您完成。所以这不是一个好方法。解决方案:我们可以使用数据适配器读取信息


第二:我们可以一次性批量更新,而不是逐个更新。批量操作有多个选项。在SQL中,您可以通过以XML格式发送信息,也可以使用表值参数TVP或您可以使用的

UPDATE cash_data .... WHERE id IN (SELECT ....)
一气呵成。否则,您可以分两步完成:首先,select收集所有ID,关闭连接,然后在obne go中对所有ID进行更新。 第二个选项的代码可能如下所示:

    public void CleanRecords()
    {
        StringBuilder builder = new StringBuilder();
        string delimiter = "";

        SQLActions.Initialize();
        SQLActions.SQL_Open();
        MySqlDataReader cashData = SQLActions.SQL_Query("SELECT `cash`.`id`, SUM(`cash`.`income_money`) AS `income_money`, `cash_data`.`total` FROM `cash_data` JOIN `cash` ON `cash`.`cash_data_id` = `cash_data`.`id` WHERE `user`='0' AND `cash_data`.`paymentterm_id`='0' OR `cash_data`.`paymentterm_id`='1' GROUP BY `cash_data_id`");
        while(cashData.Read()){
            if(cashData["income_money"].ToString() == cashData["total"].ToString()){
                builder.Append(delimiter);
                builder.Append("'" + cashData["id"].ToString() + "'");
                delimiter = ",";       
            }
        }
        SQLActions.SQL_Close();

        UpdateRecords(builder.ToString());  


    }

public void UpdateRecords(string rowIDs)
{
    SQLActions.Initialize();
    SQLActions.SQL_Open();
    SQLActions.SQL_NonQuery("UPDATE `cash_data` SET `end_date`='" + GetMeDate() + "', `user`='1' WHERE `id` IN (" + rowIDs + ")";
    SQLActions.SQL_Close();
}

那么,这个致命错误是什么呢?是否有可能给我们提供错误,如果有的话?它在标题中是在数据读取过程中遇到的致命错误连接字符串是什么?您是否已将MultipleActiveResultSets设置为True?GetMeDate做什么?您显示的查询部分可能可以在一次更新中完成,而不是读取行并逐个更新。这可能也会解决超时问题+1只是为了智能地使用分隔符,但是,这是正确的方向,除非是字符串连接,但这是另一个方向problem@Steve嗯。。。StringBuilder技术来自于我从某处复制的一段代码,因此,虽然我不再知道该将其归为谁,但我不会因此而受到赞扬。编辑:找到了,是jon Skeet,谁会想到…:杰出的非常感谢。除了stringbuilder在字符串的开头和结尾插入双引号之外,mysql无法正确理解,而且它在字符串中也看不到。我怎样才能摆脱它们?@PaulReed.builder.Append'+cashData[id].ToString+;到生成器。AppendcashData[id]。ToString;我试过了,但没用:这取决于具体情况。请阅读下面的链接
    public void CleanRecords()
    {
        StringBuilder builder = new StringBuilder();
        string delimiter = "";

        SQLActions.Initialize();
        SQLActions.SQL_Open();
        MySqlDataReader cashData = SQLActions.SQL_Query("SELECT `cash`.`id`, SUM(`cash`.`income_money`) AS `income_money`, `cash_data`.`total` FROM `cash_data` JOIN `cash` ON `cash`.`cash_data_id` = `cash_data`.`id` WHERE `user`='0' AND `cash_data`.`paymentterm_id`='0' OR `cash_data`.`paymentterm_id`='1' GROUP BY `cash_data_id`");
        while(cashData.Read()){
            if(cashData["income_money"].ToString() == cashData["total"].ToString()){
                builder.Append(delimiter);
                builder.Append("'" + cashData["id"].ToString() + "'");
                delimiter = ",";       
            }
        }
        SQLActions.SQL_Close();

        UpdateRecords(builder.ToString());  


    }

public void UpdateRecords(string rowIDs)
{
    SQLActions.Initialize();
    SQLActions.SQL_Open();
    SQLActions.SQL_NonQuery("UPDATE `cash_data` SET `end_date`='" + GetMeDate() + "', `user`='1' WHERE `id` IN (" + rowIDs + ")";
    SQLActions.SQL_Close();
}