gpt4 book ai didi

java.sql.SQLException : The result set is closed on Firebird when executing two statements

转载 作者:行者123 更新时间:2023-12-02 09:05:11 24 4
gpt4 key购买 nike

我尝试从 Firebird 2.5 DB 进行 2 个查询。我使用两个单独的 Statement 对象,但是当在第二个查询程序中尝试使用第一个查询中的数据时,会出现错误:

java.sql.SQLException: The result set is closed.

conn = DriverManager.getConnection(
strURL,
strUser, strPassword);

if (conn == null) {
System.err.println("Could not connect to database");
}

Statement stmt = conn.createStatement();
Statement statement = conn.createStatement();

ResultSet rs = stmt.executeQuery(strSQL);
ResultSet rs2 = null;

try {
while (rs.next()) {
String strSQL2 = "SELECT PATIENT_NAME_R, PATIENT_DOB, PATIENT_ID, PATIENT_SEX, PATIENT_ADDRESS_CITY, PATIENT_ADDRESS_SHF FROM PATIENTS WHERE PATIENT_UID = " + rs.getObject(1);
rs2 = statement.executeQuery(strSQL2);
try {
while (rs2.next()) {
System.out.println("СПРАВКА");
System.out.println("Ф.И.О.: " + rs2.getObject(1).toString().trim() + " Дата рождения: " + rs2.getObject(2));
System.out.println("СНИЛС: " + rs2.getObject(3));
System.out.println("Адрес: " + rs2.getObject(5) + " " + rs2.getObject(6));
System.out.println("Врач: " + rs.getString("STUDY_MD"));
System.out.println("----------------------------------------------------------------");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
} catch (SQLException e) {
e.printStackTrace();
}

while (rs2.next())System.out.println("Врач: "+ rs.getString("STUDY_MD")) 中,我得到错误

java.sql.SQLException: The result set is closed
at org.firebirdsql.jdbc.AbstractResultSet.checkOpen(AbstractResultSet.java:297)
at org.firebirdsql.jdbc.AbstractResultSet.getField(AbstractResultSet.java:788)
at org.firebirdsql.jdbc.AbstractResultSet.getString(AbstractResultSet.java:844)
at sample.Main$MedicalCert.run(Main.java:156)
at java.lang.Thread.run(Thread.java:748)

最佳答案

问题是您正在自动提交的连接上执行两个语句。在自动提交模式下,当您执行一条语句时,其他语句创建的结果集将被关闭。

JDBC 4.3 specification 中所述,在第 15.2.5 节关闭 ResultSet 对象:

A ResultSet object is implicitly closed when

  • The associated Statement object is re-executed
  • The ResultSet is created with a Holdability of CLOSE_CURSORS_AT_COMMIT and an implicit or explicit commit occurs

使用 Jaybird(Firebird JDBC 驱动程序),您有三个选择:

  1. 在执行语句之前禁用自动提交:

    conn.setAutoCommit(false);
  2. 通过执行为使第一个语句可在提交时保留

    Statement stmt = conn.createStatement(
    ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    ResultSet.HOLD_CURSORS_OVER_COMMIT);

    这将导致生成的结果集在(自动)提交后保持打开状态。但请注意,在这种模式下,Jaybird 会在内存中获取整个结果集,而不是批量获取。

  3. 与上一个选项类似,您可以通过指定连接属性 defaultResultSetHoldable 集将 Jaybird 配置为默认使用可保留结果集。另请参阅Default holdable result sets 。设置此属性将影响所有语句和结果集。

第一个选项更可取。

顺便说一句,我强烈建议您开始使用 try-with-resources :您当前的代码容易遭受资源泄漏。

正如 Kayaman 的评论中所指出的,您应该考虑重写您的查询,使其只是一个查询。您当前正在创建所谓的 N+1 查询问题(执行一条语句,然后对该语句的每一行执行另一条语句)。在查询中使用联接将允许您将其作为单个查询执行。作为警告,您的查询很容易受到存储 SQL 注入(inject)的攻击,因为您将一个值连接到查询字符串中。

关于java.sql.SQLException : The result set is closed on Firebird when executing two statements,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59873908/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com