C#报错Invalid attempt to read when no data is present,求排查解决
搞定「Invalid attempt to read when no data is present」这个错误!
兄弟,我一看你这个错误和代码片段,就知道问题出在哪了——你要么没正确走数据读取流程,要么就是查询返回空结果的时候硬去读数据了。结合你的代码,我给你捋清楚问题和修复方案:
问题根源拆解
你的代码目前有几个明显的坑:
- SQL注入大风险:直接把下拉框选中项拼进SQL字符串,这要是被坏人盯上,数据库都能给你整崩,绝对不能这么干。
- 数据读取逻辑缺失:你只创建了连接和命令,但没处理后续的读取逻辑——要么没调用
Read()方法,要么调用了但没判断有没有数据就直接读,这就触发了那个报错。 - 资源没妥善释放:SqlConnection和SqlCommand这类资源用完没及时释放,时间长了会导致数据库连接池耗尽,程序直接崩给你看。
修复后的完整代码
ICCqueueLabelDropDownList.Items.Clear(); // 用参数化查询代替字符串拼接,防注入还稳 string queryString = "SELECT [name] FROM [asterisk].[dbo].[sip_friends] WHERE name = @PhoneNumber;"; // 用using包裹资源,自动释放,不用手动关连接 using (SqlConnection conn = new SqlConnection(connectionString)) { using (SqlCommand selectCmd = new SqlCommand(queryString, conn)) { // 给参数赋值,指定类型更安全 selectCmd.Parameters.Add("@PhoneNumber", SqlDbType.VarChar).Value = phoneNumberDropDownList.SelectedItem.Text; conn.Open(); using (SqlDataReader reader = selectCmd.ExecuteReader()) { // 先判断有没有数据!这是解决错误的核心 if (reader.Read()) { // 有数据就读出来加到下拉框 string matchedName = reader["name"].ToString(); ICCqueueLabelDropDownList.Items.Add(matchedName); } else { // 没数据就给个提示,或者做你需要的处理 MessageBox.Show("没找到匹配的号码记录哦"); } } } }
重点修复说明
- 参数化查询:别再直接拼字符串了,用
@PhoneNumber占位符,把值通过参数传进去,既安全又能避免特殊字符导致的SQL语法错误。 - using语句:这些数据库资源都实现了IDisposable接口,用using包裹的话,代码块结束会自动释放资源,不用操心忘关连接的问题。
- 判断reader.Read()的返回值:
reader.Read()返回true就说明有数据可以读,false就是没数据,这样就不会出现「没数据硬读」的错误了。
额外提醒
如果你的查询可能返回多条记录,就把if改成while (reader.Read()),循环读取每一条。另外,记得先检查phoneNumberDropDownList.SelectedItem是不是null,不然会触发空引用错误,比如加个判断:
if (phoneNumberDropDownList.SelectedItem == null) { MessageBox.Show("请先选择一个号码!"); return; }
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

