如何正确退出While Reader.Read循环并规避DataReader占用错误
解决DataReader循环退出及资源冲突问题
问题根源
你手动调用rs.Close()后仍处于Using块中,Using会自动尝试释放DataReader资源,双重释放操作导致后续数据库操作报错。另外直接拼接SQL字符串存在SQL注入风险,必须修正。
最优解决方案(直接精准查询,避免循环)
既然你只需要匹配Name的那条记录,直接把SQL条件改成精确匹配,数据库直接返回目标数据,不用循环遍历,既高效又避免资源问题:
' 用参数化查询避免SQL注入,同时精确匹配Name SQLString = "Select DxccID, CountryName from CountryList where CountryName = @Name" Using command As New SqlCommand(SQLString, yourConnection) ' 替换成你的数据库连接对象 command.Parameters.AddWithValue("@Name", Name) Using rs = command.ExecuteReader() If rs.Read() Then ' 只读取第一条匹配的记录 DXCCID = rs("DxccID") CountryName = rs("CountryName") End If End Using End Using
如果必须保留LIKE查询(模糊匹配后找精确值)
如果业务上必须用LIKE模糊查询再筛选精确匹配的记录,不要手动调用rs.Close(),找到目标后直接Exit While,Using块会自动释放DataReader资源:
SQLString = "Select DxccID, CountryName from CountryList where CountryName LIKE '%' + @Name + '%'" Using command As New SqlCommand(SQLString, yourConnection) command.Parameters.AddWithValue("@Name", Name) Using rs = command.ExecuteReader() While rs.Read() DXCCID = rs("DxccID") CountryName = rs("CountryName") If CountryName = Name Then Exit While ' 找到目标直接退出循环,Using会自动关闭DataReader End If End While End Using End Using
额外注意点
- 永远不要用字符串拼接SQL,必须用参数化查询,防止注入攻击。
SqlCommand和SqlDataReader都是实现了IDisposable的对象,都要用Using包裹,确保资源自动释放,不用手动调用Dispose()或Close()。- 原代码里
command.Dispose()放在rs的Using块内是错误的,因为rs依赖command,提前释放command会导致DataReader异常。
内容的提问来源于stack exchange,提问作者Rick Ellison
相关产品推荐
相关产品推荐

