数据库存在匹配记录时rs.next()返回false无法进入while循环问题
问题描述
在如下JDBC查询逻辑中,代码执行时未进入rs.next()对应的while循环,但数据库中确实存在符合查询条件的记录,请问这种情况下ResultSet的next()返回false的原因是什么?
String sql = "SELECT * FROM tablename where name=?"; PreparedStatement smt = con.preparestatement(sql); smt.setString(1, "john"); ResultSet rs = smt.executeQuery(); ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount(); List<Object> colValues = new ArrayList<Object>(); while(rs.next()) { for(int i=1;i<=columnCount;i++) { name = rsmd.getColumnName(i); Object name1 = rs.getObject(name); colValues.add(name1); } }
排查注意事项
首先修正代码笔误:con.preparestatement(sql)为错误写法,JDBC接口的标准方法名为驼峰格式prepareStatement(Statement首字母大写),笔误会直接导致编译失败,修正后可对照以下场景排查问题。
可能的原因
- 数据库连接实例不匹配:代码所用的连接
con对应的数据库实例、库、表,和你校验数据时访问的不是同一个,比如代码连的是测试库,你校验数据用的是开发库,需确认连接URL、用户名、表名完全一致。 - 字符串匹配规则问题:
- 大小写敏感:PostgreSQL、默认配置的MySQL等数据库的字符串比较区分大小写,若库表中存储的值是
John/JOHN等和传参john大小写不一致,会直接匹配失败。 - 字段值存在冗余空格:库表中
name字段的值前后存在空格(如john、john),和传参的无空格john无法匹配,可通过调整SQL为SELECT * FROM tablename where trim(name)=?临时验证。
- 大小写敏感:PostgreSQL、默认配置的MySQL等数据库的字符串比较区分大小写,若库表中存储的值是
- 事务未提交:若匹配的记录是近期插入的,插入记录的会话未执行
commit,在JDBC连接的事务隔离级别为读提交及以上时,无法读取到未提交的记录,确认插入操作已提交事务即可。 - ResultSet指针被提前移动:若在进入
while(rs.next())之前,已经调用过rs.next()、rs.first()、rs.last()等移动指针的方法,指针已经离开初始的before-first位置,若匹配记录只有1条,再次调用next()就会返回false。 - 字符集编码不匹配:JDBC连接未配置正确的字符集参数,导致传参
john转码后和库表中存储的字符编码不一致,触发匹配失败,可在连接URL中增加useUnicode=true&characterEncoding=utf8(适配MySQL)类参数验证。 - 行级权限限制:若数据库开启了行级安全策略,当前JDBC连接使用的用户没有该条
name=john记录的查询权限,数据库会直接过滤该条记录返回空结果,不会抛出权限异常。
内容的提问来源于stack exchange,提问作者Paakiya
相关产品推荐
相关产品推荐

