복붙노트

[SQL] 어떻게 ResultSet의 자바 폐쇄 예외는 피할 수있다?

SQL

어떻게 ResultSet의 자바 폐쇄 예외는 피할 수있다?

즉시 내 코드 내 동안 (rs.next ()) 루프에 도달로는 ResultSet의 폐쇄 예외가 생성합니다. 무엇이이 예외가 발생하고 나는 그것을 어떻게 해결할 수 있습니다?

편집 : 나는 서로 동안 (rs.next ()) 루프를 중첩 오전 내 코드에서 I 통지 (rs2.next ()), 같은 DB에서 나오는 두 결과 집합이이 문제인가?

해결법

  1. ==============================

    1.당신 같은 소리는 첫 번째 문에서 결과 집합을 통과하기 전에 동일한 연결에서 다른 문을 실행. 당신이 동일한 데이터베이스에서 두 개의 결과 집합의 처리를 중첩하는 경우, 당신은 뭔가 잘못하고 있어요. 그 세트의 조합은 데이터베이스 측에서 수행해야합니다.

    당신 같은 소리는 첫 번째 문에서 결과 집합을 통과하기 전에 동일한 연결에서 다른 문을 실행. 당신이 동일한 데이터베이스에서 두 개의 결과 집합의 처리를 중첩하는 경우, 당신은 뭔가 잘못하고 있어요. 그 세트의 조합은 데이터베이스 측에서 수행해야합니다.

  2. ==============================

    2.이것은 당신이 사용중인 드라이버를 포함하여 여러 가지 이유에 의해 발생할 수 있습니다.

    이것은 당신이 사용중인 드라이버를 포함하여 여러 가지 이유에 의해 발생할 수 있습니다.

    A) 일부 드라이버는 중첩 문을 허용하지 않습니다. Statement 객체를 생성 할 때 드라이버가 지원하는 JDBC 3.0 세 번째 매개 변수를 확인해야합니다 경우에 따라. 예를 들어, 나는 파이어 버드에 JayBird 드라이버와 같은 문제가 있었지만 코드는 포스트 그레스 드라이버와 함께 벌금을했다. 그럼 난의 createStatement 메서드 호출에 세 번째 매개 변수를 추가 ResultSet.HOLD_CURSORS_OVER_COMMIT로 설정하고, 코드가 너무 파이어 버드에 대한 잘 작동하기 시작했다.

    static void testNestedRS() throws SQLException {
    
        Connection con =null;
        try {
            // GET A CONNECTION
            con = ConexionDesdeArchivo.obtenerConexion("examen-dest");
            String sql1 = "select * from reportes_clasificacion";
    
            Statement st1 = con.createStatement(
                    ResultSet.TYPE_SCROLL_INSENSITIVE,
                    ResultSet.CONCUR_READ_ONLY, 
                    ResultSet.HOLD_CURSORS_OVER_COMMIT);
            ResultSet rs1 = null;
    
            try {
                // EXECUTE THE FIRST QRY
                rs1 = st1.executeQuery(sql1);
    
                while (rs1.next()) {
                    // THIS LINE WILL BE PRINTED JUST ONCE ON
                                        // SOME DRIVERS UNLESS YOU CREATE THE STATEMENT 
                    // WITH 3 PARAMETERS USING 
                                        // ResultSet.HOLD_CURSORS_OVER_COMMIT
                    System.out.println("ST1 Row #: " + rs1.getRow());
    
                    String sql2 = "select * from reportes";
                    Statement st2 = con.createStatement(
                            ResultSet.TYPE_SCROLL_INSENSITIVE,
                            ResultSet.CONCUR_READ_ONLY);
    
                    // EXECUTE THE SECOND QRY.  THIS CLOSES THE FIRST 
                    // ResultSet ON SOME DRIVERS WITHOUT USING 
                                        // ResultSet.HOLD_CURSORS_OVER_COMMIT
    
                    st2.executeQuery(sql2);
    
                    st2.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                rs1.close();
                st1.close();
            }
    
        } catch (SQLException e) {
    
        } finally {
            con.close();
    
        }
    
    }
    

    b)는 코드에서 버그가있을 수 있습니다. 같은 문 개체에 대한 쿼리를 다시 실행하면 당신이 Statement 객체를 다시 사용할 수 없습니다 기억, 진술과 관련된 모든 열린 결과 집합이 닫힙니다. 확인 당신은 문을 닫을 수 없습니다.

  3. ==============================

    3.또한, 각 문에서 열린 한 결과 집합을 가질 수 있습니다. 동시에 두 개의 결과 집합을 반복하는 경우에 따라서, 반드시 서로 다른 문에 실행합니다. 암시 적으로 가까운 하나 개의 문장에 첫 번째 결과 집합을 것입니다 열기. http://java.sun.com/javase/6/docs/api/java/sql/Statement.html

    또한, 각 문에서 열린 한 결과 집합을 가질 수 있습니다. 동시에 두 개의 결과 집합을 반복하는 경우에 따라서, 반드시 서로 다른 문에 실행합니다. 암시 적으로 가까운 하나 개의 문장에 첫 번째 결과 집합을 것입니다 열기. http://java.sun.com/javase/6/docs/api/java/sql/Statement.html

  4. ==============================

    4.예외는 결과가 닫혀 있는지 말한다. 당신이 ResultSet.close () 호출을 발행 어디 당신은 당신의 코드와 모든 위치에 대한 모양을 검사해야합니다. 또한 Statement.close ()과의 Connection.close ()를 찾습니다. 확실히, 그 중 하나는 ()를 호출 rs.next 전에 호출됩니다.

    예외는 결과가 닫혀 있는지 말한다. 당신이 ResultSet.close () 호출을 발행 어디 당신은 당신의 코드와 모든 위치에 대한 모양을 검사해야합니다. 또한 Statement.close ()과의 Connection.close ()를 찾습니다. 확실히, 그 중 하나는 ()를 호출 rs.next 전에 호출됩니다.

  5. ==============================

    5.당신은뿐만 아니라 폐쇄 된 ResultSet으로 이어질 것의 ResultSet을 만든 닫힌 연결 또는 문 중 하나를 가질 수있다.

    당신은뿐만 아니라 폐쇄 된 ResultSet으로 이어질 것의 ResultSet을 만든 닫힌 연결 또는 문 중 하나를 가질 수있다.

  6. ==============================

    6.적절한 JDBC 호출의 모양은 다음과 같습니다

    적절한 JDBC 호출의 모양은 다음과 같습니다

    try { 
        Connection conn;
        Statement stmt;
        ResultSet rs; 
    
        try {
            conn = DriverManager.getConnection(myUrl,"",""); 
            stmt = conn.createStatement(); 
            rs = stmt.executeQuery(myQuery); 
    
            while ( rs.next() ) { 
                // process results
            } 
    
        } catch (SqlException e) { 
            System.err.println("Got an exception! "); 
            System.err.println(e.getMessage()); 
        } finally {
            // you should release your resources here
            if (rs != null) { 
                rs.close();
            }
    
            if (stmt != null) {
                stmt.close();
            }
    
            if (conn != null) {
                conn.close();
            }
        }
    } catch (SqlException e) {
        System.err.println("Got an exception! "); 
        System.err.println(e.getMessage()); 
    }
    

    당신은 당신이 결과 세트에서 결과를 얻을 후에 만 ​​연결 (또는 성명)을 닫을 수 있습니다. 가장 안전한 방법은 finally 블록에서 할 것입니다. 그러나 close ()를 할 수도 고투 SQLEXCEPTION, 따라서 다른 시도-catch 블록.

  7. ==============================

    7.나는 같은 오류 모두는 내가 실행하고 데이터베이스를 업데이트 같은 문 인터페이스 객체를 사용하고 정확했다 얻었다. 쿼리 즉 분리하기 위해 업데이트 명령문 인터페이스가 다른 객체를 사용하여 실행 한 후이 오류를 해결. 즉, 업데이트 및 쿼리를 실행 모두에 대해 동일한 명령문 객체를 사용하지 않는이에서 제거합니까.

    나는 같은 오류 모두는 내가 실행하고 데이터베이스를 업데이트 같은 문 인터페이스 객체를 사용하고 정확했다 얻었다. 쿼리 즉 분리하기 위해 업데이트 명령문 인터페이스가 다른 객체를 사용하여 실행 한 후이 오류를 해결. 즉, 업데이트 및 쿼리를 실행 모두에 대해 동일한 명령문 객체를 사용하지 않는이에서 제거합니까.

  8. ==============================

    8.이 코드는 정적으로 실행되는 경우이 방법을 선언 여부를 확인합니다. 이 정적 인 경우의 ResultSet을 다시 다른 스레드가있을 수 있습니다.

    이 코드는 정적으로 실행되는 경우이 방법을 선언 여부를 확인합니다. 이 정적 인 경우의 ResultSet을 다시 다른 스레드가있을 수 있습니다.

  9. ==============================

    9.rs.next을 실행하기 전에 당신이 폐쇄 한 모든 문 및 결과 세트를 확인하십시오. 마침내이 보장

    rs.next을 실행하기 전에 당신이 폐쇄 한 모든 문 및 결과 세트를 확인하십시오. 마침내이 보장

    public boolean flowExists( Integer idStatusPrevious, Integer idStatus, Connection connection ) {
        LogUtil.logRequestMethod();
    
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = connection.prepareStatement( Constants.SCRIPT_SELECT_FIND_FLOW_STATUS_BY_STATUS );
            ps.setInt( 1, idStatusPrevious );
            ps.setInt( 2, idStatus );
    
            rs = ps.executeQuery();
    
            Long count = 0L;
    
            if ( rs != null ) {
                while ( rs.next() ) {
                    count = rs.getLong( 1 );
                    break;
                }
            }
    
            LogUtil.logSuccessMethod();
    
            return count > 0L;
        } catch ( Exception e ) {
            String errorMsg = String
                .format( Constants.ERROR_FINALIZED_METHOD, ( e.getMessage() != null ? e.getMessage() : "" ) );
            LogUtil.logError( errorMsg, e );
    
            throw new FatalException( errorMsg );
        } finally {
            rs.close();
            ps.close();
        }
    
  10. ==============================

    10.ResultSet의 닫힌 예외는 두 가지 이유로 발생 될 수 있습니다.

    ResultSet의 닫힌 예외는 두 가지 이유로 발생 될 수 있습니다.

    1) 당신은 다른 모든 연결을 닫지 않고 데이터베이스에 다른 연결을 열었습니다.

    2) 귀하의 ResultSet는 어떤 값을 반환 할 수 없습니다. 당신이 ResultSet의 자바에서 데이터에 액세스하려고 할 때 그래서 ResultSetClosedException 발생합니다.

  11. from https://stackoverflow.com/questions/935511/how-can-i-avoid-resultset-is-closed-exception-in-java by cc-by-sa and MIT license