读取数据时遇到 C# 致命错误
Posted
技术标签:
【中文标题】读取数据时遇到 C# 致命错误【英文标题】:C# Fatal error encoutered during data read 【发布时间】:2013-06-17 08:01:15 【问题描述】:我从数据库中选择了大约 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 的最大值将解决我的问题,但看起来这在我的情况下不起作用。 有任何想法吗? :)
编辑: 我得到的错误是“数据读取期间遇到的致命错误”。
更新:
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();
【问题讨论】:
那么这个“致命错误”是什么? 是否可以给我们错误,如果有的话? 它在标题“数据读取期间遇到的致命错误”中 你的连接字符串是什么?您是否设置了 MultipleActiveResultSets=True? GetMeDate() 有什么作用?您显示的查询部分可能会在一次更新中完成(而不是读取行并一一更新)。这也可能会解决您的超时问题 【参考方案1】:你可以使用
UPDATE cash_data .... WHERE id IN (SELECT ....)
一口气做完所有事情。否则,您可以分两步完成:首先选择收集所有 id,关闭连接,然后使用所有 id 在 obne go 中进行更新。 第二个选项的代码可能如下所示:
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 只是为了巧妙地使用分隔符,但是,这是正确的方向,除非用于字符串连接,但这是另一个问题 @Steve ehm... StringBuilder 技术来自我从某处复制的代码的 sn-p,因此(虽然我不再知道将其归因于谁)我不会将其归功于它。编辑:找到了,是 jon Skeet,谁会想到... :) ***.com/questions/581448/… 太棒了!谢谢!除了我猜的stringbuilder在字符串的开头和结尾插入双引号(“),mysql不能正确理解并且它不会在字符串中查找。我怎样才能摆脱它们? @PaulReed ty 将builder.Append("'" + cashData["id"].ToString() + "'");
更改为 builder.Append(cashData["id"].ToString())
;
试过了,但没有帮助:(【参考方案2】:
有多个问题:
首先:您使用数据阅读器读取了大约 20K 的信息,然后在阅读器本身中逐一进行更新。阅读器保持连接打开,直到您完成。所以这不是做这件事的好方法。解决方案:我们可以使用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)
【讨论】:
视情况而定。请阅读以下链接***.com/questions/1676753/…以上是关于读取数据时遇到 C# 致命错误的主要内容,如果未能解决你的问题,请参考以下文章
读取 Firebase 数据:线程 1:致命错误:在展开可选值时意外发现 nil
MySqlClient EndOfStreamException:尝试读取流结束时发生致命错误