【问题标题】:Multiple ResultSets, different queries, same database SQLSERVER多个结果集,不同的查询,相同的数据库 SQL SERVER
【发布时间】:2014-01-30 16:50:19
【问题描述】:

使用 JDBC 驱动程序,我如何使用来自不同查询的多个结果集而无需不断打开和关闭连接,因为它可以提取我需要的东西并将其传递给另一个方法。每次打开一个新的连接、语句和结果集

public static void OppQuery() {
    Connection conn = null;
    Statement stmt = null;
    ResultSet result_set = null;
    try {
        Class.forName(JDBC_DRIVER);
        conn = DriverManager.getConnection(DB_URL);
        stmt = conn.createStatement();

        String emailInfoQuery = "FROM WHERE";
}


public static void addQuery(String latestRenewalId) {
    Connection conn = null;
    Statement stmt = null;
    ResultSet result_set = null;
    try {
        Class.forName(JDBC_DRIVER);
        conn = DriverManager.getConnection(DB_URL);
        stmt = conn.createStatement();
        String new_AddressLine1, new_AddressLine2;
        new_AddressLine1=new_AddressLine2="";
        int new_ChannelOption= 0;
}

我尝试在一种方法中使用多个结果集,但它不断抛出异常,说结果集已关闭。我对 SqlServver 没有太多经验,因此任何指导都会有所帮助:-)

【问题讨论】:

  • 您当前的代码没有您描述的问题(但似乎也不完整)
  • 我想知道我是否可以避免这种情况并组合成一种方法,而无需通过一个连接将所有内容分开

标签: java sql-server jdbc


【解决方案1】:

在 JDBC 中,当连接处于自动提交模式(默认)时,任何语句的执行都会提交上一个事务并关闭同一连接上所有打开的结果集(假设可保持性为ResultSet.CLOSE_CURSORS_AT_COMMIT ,实际上是isn't the default for SQL Server)。当您需要打开多个结果集时,您需要禁用自动提交(或使用ResultSet.HOLD_CURSORS_OVER_COMMIT并且您需要使用多个Statement 对象。 JDBC 要求在同一 Statement 对象上执行新的操作会关闭来自同一语句的任何其他打开的结果集。

所以

  1. 禁用自动提交 (Connection.setAutoCommit(false))
  2. 使用多个Statement对象打开ResultSets

【讨论】:

  • 我理解为什么需要多个 Statement 对象,但我不太确定自动提交要求。看here
  • 规范(第 10 章)说:“通常,当当前 SQL 语句需要一个新事务并且没有事务已经到位时,就会启动一个新事务。[...] 启用自动提交会导致在每个单独的 SQL 语句完成后立即提交事务”。 JDBC 有一个“每个连接一个事务”模型,所以如果一个事务以Statement 的执行开始,这意味着前一个事务将被提交(或回滚),因此任何打开的ResultSet 都将被关闭(除了可持有的ResultSets)。
  • @GordThompson Microsoft SQL Server JDBC 驱动程序默认使用可保持的ResultSets,请参阅Using Holdability
【解决方案2】:

进一步了解 Mark 的回答,由于 Microsoft SQL Server JDBC 驱动程序似乎默认创建“Holdable” ResultSet 对象,因此启用 AutoCommit 时,以下测试代码确实有效:

import java.sql.*;

public class SqlServerTest {

    public static void main(String[] args) {
        try {
            String connectionUrl =
                    "jdbc:sqlserver://localhost:52865;" +
                    "databaseName=myDb;" +
                    "integratedSecurity=true";
            Connection con = DriverManager.getConnection(connectionUrl);
            System.out.println(String.format("con.getAutoCommit returned %s", con.getAutoCommit()));

            Statement st1 = con.createStatement();
            ResultSet rs1 = st1.executeQuery("SELECT id FROM odds");
            rs1.next();
            System.out.println(String.format("value from rs1: %d", rs1.getInt(1)));

            Statement st2 = con.createStatement();
            ResultSet rs2 = st2.executeQuery("SELECT id FROM evens");
            rs2.next();
            System.out.println(String.format("value from rs2: %d", rs2.getInt(1)));

            rs1.next();
            System.out.println(String.format("value from rs1: %d", rs1.getInt(1)));

            rs2.next();
            System.out.println(String.format("value from rs2: %d", rs2.getInt(1)));

            rs2.close();
            rs1.close();
            con.close();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

}

对于名为 [odds] 的表中的测试数据...

id  description
--  -----------
 1  one
 3  three
 5  five

...和[偶数]...

id  description
--  -----------
 2  two
 4  four
 6  six

...控制台输出为:

con.getAutoCommit returned true
value from rs1: 1
value from rs2: 2
value from rs1: 3
value from rs2: 4

【讨论】:

    猜你喜欢
    • 2014-07-06
    • 1970-01-01
    • 2011-06-24
    • 2021-10-27
    • 1970-01-01
    • 1970-01-01
    • 2019-06-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多