You need to enable JavaScript to run this app. JSP使用JDBC读取数据时next()嵌套while循环首次迭代后失效
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.15 01:54:04