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

时间:2013-06-17 08:01:15

标签: c# mysql datareader

我从数据库中选择了大约20,000条记录,然后我逐一更新它们 我查找了这个错误,我看到设置CommandTimeout会有所帮助,但不是我的情况。

        public void Initialize()
    {
        MySqlConnectionStringBuilder SQLConnect = new MySqlConnectionStringBuilder();
        SQLConnect.Server = SQLServer;
        SQLConnect.UserID = SQLUser;
        SQLConnect.Password = SQLPassword;
        SQLConnect.Database = SQLDatabase;
        SQLConnect.Port = SQLPort;
        SQLConnection = new MySqlConnection(SQLConnect.ToString());
    }

        public MySqlDataReader SQL_Query(string query)
    {
        MySqlCommand sql_command;
        sql_command = SQLConnection.CreateCommand();
        sql_command.CommandTimeout = int.MaxValue;
        sql_command.CommandText = query;
        MySqlDataReader query_result = sql_command.ExecuteReader();
        return query_result;
    }

        public void SQL_NonQuery(string query)
    {
        MySqlCommand sql_command;
        sql_command = SQLConnection.CreateCommand();
        sql_command.CommandTimeout = int.MaxValue;
        sql_command.CommandText = query;
        sql_command.ExecuteNonQuery();
    }

这是我的方法,它使选择查询:

        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();
    }

2 个答案:

答案 0 :(得分:1)

您可以使用

UPDATE cash_data .... WHERE id IN (SELECT ....)

并一气呵成。否则,您可以分两步完成:首先选择收集所有ID,关闭连接,然后在obne中执行更新,并使用所有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();
}

答案 1 :(得分:0)

有多个问题:

首先:您使用数据读取器读取大约20K的信息,然后在读取器中逐个更新。在您完成之前,Reader会保持连接处于打开状态。所以这不是做这件事的好方法。解决方案:我们可以使用Data Adapter读取信息。

第二:我们可以一次性批量更新,而不是逐个更新。批量操作有多种选择。在SQL中,您可以通过以XML格式发送信息,也可以使用表值参数(TVP)(http://www.codeproject.com/Articles/22205/ADO-NET-and-OPENXML-to-Perform-Bulk-Database-Opera)或(http://dev.mysql.com/doc/refman/5.5/en/load-xml.html