ResultSet 关闭后不允许操作 (mysql, java)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32671535/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 20:36:20  来源:igfitidea点击:

Operation not allowed after ResultSet closed (mysql, java)

javamysqlsql

提问by ratnesh

I was stuck with the error , here my line number 42 is while(rs.next()){, please help me with this i am stuck at this for few hrs.

我被错误困住了,这里我的第 42 行是while(rs.next()){,请帮我解决这个问题,我被困在这里几个小时。

> Exception in thread "main" java.sql.SQLException: Operation not allowed after ResultSet closed
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:998)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:937)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:872)
    at com.mysql.jdbc.ResultSetImpl.checkClosed(ResultSetImpl.java:740)
    at com.mysql.jdbc.ResultSetImpl.next(ResultSetImpl.java:6326)
    at removeStopwords.RemoveStopwords.main(RemoveStopwords.java:42)

This is my code:

这是我的代码:

package removeStopwords;

import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.StringTokenizer;

import com.mysql.jdbc.Connection;
import com.mysql.jdbc.Statement;

public class RemoveStopwords {

    // JDBC driver name and database URL
    static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
    static final String DB_URL = "jdbc:mysql://localhost/mydbv2";

    // Database credentials
    static final String USER = "root";
    static final String PASS = "***";

    public static void main(String[] args) throws ClassNotFoundException, SQLException {

        Connection conn = null;
        Statement stmt = null;

        Class.forName("com.mysql.jdbc.Driver");

        conn = (Connection) DriverManager.getConnection(DB_URL, USER, PASS);

        stmt = (Statement) conn.createStatement();
        String sql;
        ResultSet rs = null;
        ResultSet rs2 = null;
        ResultSet rs3 = null;
        java.sql.PreparedStatement ps = null;
        int event_id = 10;
        sql = "SELECT id,text from tweet where event_id = " + event_id;
        rs = stmt.executeQuery(sql);

        String text = "";
        Long id;
        while (rs.next()) {
            id = rs.getLong("id");
            text = rs.getString("text");
            System.out.println("tweet = " + text);
            text = text.replaceAll("http[^\s]+", "");
            text = text.replaceAll("www[^\s]+", "");
            System.out.println("tweet after removal of links= " + text);

            StringTokenizer st = new StringTokenizer(text);
            while (st.hasMoreTokens()) {
                String stopword = st.nextToken();
                System.out.println("stopword : " + stopword);

                sql = "SELECT * from stopwords WHERE word =" + '"'+stopword+'"';
                rs2 = stmt.executeQuery(sql);
                if (rs2.next()) {
                    text = text.replaceAll(stopword, "");
                    System.out.println("tweet after removing stopword = " + text);
                }
                sql = "SELECT * from filtertweet where tweet_id = " + id + "";
                rs3 = stmt.executeQuery(sql);
                if (!rs3.next()) {
                    sql = "INSERT INTO filtertweet VALUES(?,?)";
                    ps = conn.prepareStatement(sql);
                    ps.setLong(1, id);
                    ps.setString(2, text);
                    ps.executeUpdate();
                }

            }
        }
        stmt.close();
        conn.close();
    }

}

回答by Andreas

A Statementobject can have only one active ResultSet, so when you execute rs2 = stmt.executeQuery(sql), the first ResultSet (rs) gets closed.

一个Statement对象只能有一个 active ResultSet,因此当您执行时rs2 = stmt.executeQuery(sql),第一个 ResultSet( rs) 将关闭。

Create two Statementobjects, one for rsand another for rs2.

创建两个Statement对象,一个用于rs,另一个用于rs2

Quoting the javadoc of Statement:

引用 javadoc 的Statement

By default, only one ResultSetobject per Statementobject can be open at the same time. Therefore, if the reading of one ResultSetobject is interleaved with the reading of another, each must have been generated by different Statementobjects. All execution methods in the Statementinterface implicitly close a statment's current ResultSetobject if an open one exists.

默认情况下,ResultSet每个Statement对象只能同时打开一个对象。因此,如果一个ResultSet对象的读取与另一个对象的读取交织在一起,则每个Statement对象都必须由不同的对象生成。如果存在打开StatementResultSet对象,则接口中的所有执行方法都会隐式关闭语句的当前对象。

回答by Harish Sridharan

One ResultSet for one Statement is valid. When you are executing multiple queries use various Statements.

一个 Statement 的一个 ResultSet 是有效的。当您执行多个查询时,请使用各种语句。

public static void main(String[] args) throws ClassNotFoundException, SQLException {

    Connection conn = null;
    Statement stmt = null;

    Class.forName("com.mysql.jdbc.Driver");

    conn = (Connection) DriverManager.getConnection(DB_URL, USER, PASS);

    stmt = (Statement) conn.createStatement();
    String sql;
    ResultSet rs = null;
    ResultSet rs2 = null;
    ResultSet rs3 = null;
    java.sql.PreparedStatement ps = null;
    int event_id = 10;
    sql = "SELECT id,text from tweet where event_id = " + event_id;
    rs = stmt.executeQuery(sql);

    String text = "";
    Long id;
    while (rs.next()) {
        id = rs.getLong("id");
        text = rs.getString("text");
        System.out.println("tweet = " + text);
        text = text.replaceAll("http[^\s]+", "");
        text = text.replaceAll("www[^\s]+", "");
        System.out.println("tweet after removal of links= " + text);

        StringTokenizer st = new StringTokenizer(text);
        while (st.hasMoreTokens()) {
            String stopword = st.nextToken();
            System.out.println("stopword : " + stopword);

            sql = "SELECT * from stopwords WHERE word =" + '"'+stopword+'"';

            Statement stmt2 = conn.createStatement();
            rs2 = stmt2.executeQuery(sql);
            if (rs2.next()) {
                text = text.replaceAll(stopword, "");
                System.out.println("tweet after removing stopword = " + text);
            }
            sql = "SELECT * from filtertweet where tweet_id = " + id + "";

            Statement stmt3 = conn.createStatement();
            rs3 = stmt3.executeQuery(sql);
            if (!rs3.next()) {
                sql = "INSERT INTO filtertweet VALUES(?,?)";
                ps = conn.prepareStatement(sql);
                ps.setLong(1, id);
                ps.setString(2, text);
                ps.executeUpdate();
            }

        }
    }
    stmt.close();
    conn.close();
}