Java 使用方法next()时,异常结果集关闭

Java 使用方法next()时,异常结果集关闭,java,sql,jdbc,Java,Sql,Jdbc,当我尝试从while(sr.next())向表中插入值时,next()方法遇到了问题。它会引发ResultSet异常,但当我从while的主体中删除insert查询时,它会工作。那么,当我在while主体中插入值时,为什么ResultSet会关闭呢 import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java

当我尝试从while(sr.next())向表中插入值时,next()方法遇到了问题。它会引发ResultSet异常,但当我从while的主体中删除insert查询时,它会工作。那么,当我在while主体中插入值时,为什么ResultSet会关闭呢

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;

public class SqlServerJDBC {


    public static void main(String[] args) throws IOException {
        String line, dis;
        float totalPrice = 0;
        Scanner scan= new Scanner(System.in);

        try {
                    Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
                    System.out.println("# - Driver Loaded");

                    Connection con =               DriverManager.getConnection("jdbc:odbc:books_DSN");
                    System.out.println("# - Connection Obtained");

                    Statement stmt = con.createStatement();
                    System.out.println("# - Statement Created");

                    String createTableOrder =  "create table viewOrder"
                                            + "(title_name VARCHAR(40),"
                                            + "price DECIMAL(5,2),"
                                            + "pages INT,"
                                            + "au_fname VARCHAR(15),"
                                            + "au_lname VARCHAR(15),"
                                            + "pub_name VARCHAR(20),"
                                            + "city VARCHAR(15),"
                                            + "country VARCHAR(15))";



                    stmt.executeUpdate(createTableOrder);
                    System.out.println("Created table in given database...");

                    ResultSet rs = stmt.executeQuery("SELECT title_name,price FROM titless");
                    System.out.println("# - Query Executed\n");

                    while(rs.next()){
                        System.out.println("title: " +rs.getString("title_name") + "\tprice: " + rs.getFloat("price"));             
                    }   

                        do {
                            System.out.println("\nEnter the name of the book...");
                            line = scan.nextLine();
                            rs = stmt.executeQuery("select title_name,price,pages,au_fname"
                                    + ",au_lname,pub_name,authorss.city,country "
                                    + " from titless inner join title_authorss on titless.title_id = title_authorss.title_id "
                                    + " inner join authorss on title_authorss.au_id = authorss.au_id"
                                    + " inner join publisherss on publisherss.pub_id = titless.pub_id"
                                    + " where titless.title_name like "+"'"+line+"'");


                            /*here is the problem */
                                while(rs.next()){

                                String insertIntoTableOrder =("INSERT INTO viewOrder "
                                        + " VALUES ('"+rs.getString("title_name")+"',"+rs.getFloat("price")+","+rs.getInt("pages")+""
                                        + ",'"+rs.getString("au_fname")+"','"+rs.getString("au_lname")+"',"
                                        + "'"+rs.getString("pub_name")+"','"+rs.getString("city")+"','"+rs.getString("country")+"')");
                                stmt.executeUpdate(insertIntoTableOrder);

                                totalPrice = totalPrice + rs.getFloat("price"); 


                            }


                            System.out.println("Total Price = " + totalPrice);
                            System.out.println("Do you want add more books ??");
                            System.out.println("Y/N...");
                            dis = scan.nextLine();


                        } while (dis.equalsIgnoreCase("y")); 



                         con.close();
                         stmt.close();   
                         rs.close();

                    System.out.println("# - Resources released");

                } catch (SQLException | ClassNotFoundException ex) {
                            System.out.println("Error : "+ex);
           }

    }   

  }

您需要另一个语句对象。在迭代ResultSet(与同一语句上的光标相连)时,对单条语句调用第二个查询是个坏主意。

根据文档:

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

您正在迭代您的
结果集
,并重用相同的
语句
来执行
插入
。执行insert后,正在迭代的
ResultSet
将关闭,对
rs.next()
的下一次调用将抛出该异常。您需要使用新的
语句
在循环内执行insert查询

也就是说,您确实应该为SQL使用准备好的语句。它在读取代码方面更干净,并且在为您处理任何必要的引用时更不容易出错

String statementString = "INSERT INTO viewOrder VALUES (?,?,?,?,?,?,?,?)";
PreparedStatement pStmt= con.prepareStatement(statementString);
while(rs.next())
{
    pStmt.setString(1, rs.getString("title_name"));
    pStmt.setFloat(2, rs.getFloat("price"));
    pStmt.setInt(3, rs.getInt("pages"));
    pStmt.setString(4, rs.getString("au_fname"));
    pStmt.setString(5, rs.getString("au_lname"));
    pStmt.setString(6, rs.getString("pub_name"));
    pStmt.setString(7, rs.getString("city"));
    pStmt.setString(8, rs.getString("country"));
    pStmt.execute();

    totalPrice = totalPrice + rs.getFloat("price"); 
}

在获得获取rs.next()的机会之前关闭while循环似乎在rs.next while循环内对同一个ResultSet对象运行executeQuery。这有什么原因吗?如果您使用不同的ResultSet对象,可能会解决此问题?似乎也不是问题所在。因为在这种情况下,您只会得到某种数据库资源异常。在它旁边,我想一定有某种逻辑问题。呃,不。。。他完全按照我说的做了,并且得到了人们所期望的完全不同的结果。不存在“逻辑问题”,如果他在insert中使用单独的语句,那么它就可以正常工作。