JSP使用JDBC读取数据时next()嵌套while循环首次迭代后失效
问题根因
JDBC规范规定,同一个Statement实例同一时间只能关联一个打开的ResultSet对象。你使用同一个statement对象先执行了问题查询得到resultQuestions,在循环中又用同一个statement执行选项查询,此时之前打开的resultQuestions会被隐式关闭,因此内层选项循环跑完后,外层调用resultQuestions.next()时对应的结果集已经失效,无法继续迭代。
解决方案
方案1:拆分Statement对象(适配现有嵌套查询逻辑)
创建两个独立的Statement对象,分别处理问题查询和选项查询,避免两个结果集互相干扰,修改后的核心代码如下:
Connection connection = null; Statement stmtQuestion = null; Statement stmtOption = null; ResultSet resultQuestions = null; ResultSet resultOptions = null; try{ connection = DriverManager.getConnection(connectionUrl+dbName, userId, password); // 创建两个独立的Statement stmtQuestion = connection.createStatement(); stmtOption = connection.createStatement(); String qsql ="SELECT * FROM questionsDB"; resultQuestions = stmtQuestion.executeQuery(qsql); while(resultQuestions.next()) { // 直接用getInt获取qid,无需额外类型转换 int curQuestion= resultQuestions.getInt("qid"); %> <%= curQuestion %> <%=resultQuestions.getString("questionmessage") %> <% String osql ="SELECT * FROM optionsDB WHERE qid="+curQuestion; resultOptions = stmtOption.executeQuery(osql); while(resultOptions.next()) { %> <%=resultOptions.getString("optionmessage") %> <% } // 用完及时关闭选项结果集释放资源 if(resultOptions != null) resultOptions.close(); } } catch (Exception e) { e.printStackTrace(); } finally { // 按顺序关闭所有资源避免泄漏:ResultSet → Statement → Connection if(resultQuestions != null) try {resultQuestions.close();} catch(SQLException e) {} if(stmtQuestion != null) try {stmtQuestion.close();} catch(SQLException e) {} if(stmtOption != null) try {stmtOption.close();} catch(SQLException e) {} if(connection != null) try {connection.close();} catch(SQLException e) {} }
方案2:联表查询(更推荐,性能更优)
不用嵌套查询,直接通过SQL左连接一次拿到所有问题和对应选项,仅需一次数据库请求,代码逻辑更简洁:
String joinSql = "SELECT q.qid, q.questionmessage, o.optionmessage FROM questionsDB q LEFT JOIN optionsDB o ON q.qid = o.qid ORDER BY q.qid"; ResultSet rs = statement.executeQuery(joinSql); int lastQid = -1; while(rs.next()) { int curQid = rs.getInt("qid"); // 遇到新问题时输出问题内容 if(curQid != lastQid) { %> <br><%= curQid %> <%= rs.getString("questionmessage") %><br> <% lastQid = curQid; } %> <%= rs.getString("optionmessage") %><br> <% }
额外优化提示
你当前页面编码设置为ISO-8859-1,如果问题或选项包含中文会出现乱码,建议将页面编码修改为UTF-8。
内容的提问来源于stack exchange,提问作者HARIRAM
相关产品推荐
相关产品推荐

