MySqlDataReader仅首次可读取数据,后续调用返回空值求助
搞定你的MySQL查询重复调用空结果问题
嘿,我一眼就瞅出你代码里的症结了——MySqlDataReader没有被正确释放,导致数据库连接被持续占用,所以第一次查询能正常跑,后面再调用的时候,连接被之前的Reader占着,根本没法执行新的查询,自然返回空字符串啦。
具体为啥会这样?
默认情况下,一个数据库连接同一时间只能有一个活跃的DataReader。你第一次执行查询后,reader一直没关闭,这个连接就被“锁”住了。后续再执行command.ExecuteReader()的时候,连接没法处理新的命令,结果自然是空的。
另外你的代码还有两个小坑得注意:
- 直接用字符串拼接SQL语句(
"SELECT * FROM " + table),这可是SQL注入的高危操作,千万不能在生产环境这么写! - 异常捕获块是空的,万一出了错你连啥原因都查不到,太不利于调试了。
修复后的代码
给你改好的版本,用using语句自动释放MySqlCommand和MySqlDataReader,确保资源用完就回收:
System.String result = ""; try { // 用using包裹,自动释放资源,不用手动Close using (MySql.Data.MySqlClient.MySqlCommand command = new MySql.Data.MySqlClient.MySqlCommand($"SELECT {column} FROM {table}", m_Connection)) using (MySql.Data.MySqlClient.MySqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { result += ((string)reader[column]); result += ";"; } } } catch (System.Exception ex) { // 至少加个错误输出,方便排查问题 Console.WriteLine($"查询失败: {ex.Message}"); } return result;
额外优化建议
- 防SQL注入:如果
table和column是动态传入的,一定要做白名单验证(比如检查是否是允许的表/列名),因为表名和列名没法用参数化查询来保护。 - 用StringBuilder提升性能:如果返回的数据量比较大,
result += "..."会频繁创建新字符串,性能拉胯。换成StringBuilder会高效很多:
System.Text.StringBuilder resultBuilder = new System.Text.StringBuilder(); // ... while (reader.Read()) { resultBuilder.Append((string)reader[column]); resultBuilder.Append(";"); } string result = resultBuilder.ToString();
- 检查连接状态:每次查询前确认连接是打开的,比如在try块开头加一句:
if (m_Connection.State != System.Data.ConnectionState.Open) m_Connection.Open();
内容的提问来源于stack exchange,提问作者Harold Trotter
相关产品推荐
相关产品推荐

