source

JDBC가 빈 결과 집합을 반환합니다.

manycodes 2023. 6. 20. 21:42
반응형

JDBC가 빈 결과 집합을 반환합니다.

매우 간단한 데이터베이스 연결을 위해 JDBC를 사용하고 있습니다.

연결/문을 만들고 쿼리를 실행했습니다.디버거에서 문의 쿼리 개체를 확인하여 올바른 쿼리를 보내고 있는지 확인합니다.그런 다음 데이터베이스에서 쿼리(디버거에서 직접 복사)를 두 번 확인하여 데이터가 반환되는지 확인했습니다.그러나 반환된 결과 집합은 .next()에서 false를 제공합니다.

여기서 제가 놓치는 흔한 함정이 있나요?

public List<InterestGroup> getGroups() {
    myDB.sendQuery("select distinct group_name From group_members where
            username='" + this.username + "'");
    ResultSet results = myDB.getResults();
    List<InterestGroup> returnList = new ArrayList<InterestGroup>();
    try {
        while (results.next()) {
            returnList.add(new InterestGroup(results.getString("group_name"), myDB));
        } 
        return returnList;
    } catch (SQLException e) {
        e.printStackTrace();
        return null;
    }

}

그리고 myDB 클래스(모든 프로젝트에 연결/문 코드를 넣을 수 있는 간단한 래퍼)

public void sendQuery(String query){
    this.query = query;
    try {
        if(statement == null){
            statement = connection.createStatement();
        }
        results = statement.executeQuery(query);
    } catch (SQLException e) {
        System.out.println(query);
        currentError = e;
        results = null;
        printError(e, "querying");
    }

}

public ResultSet getResults(){
    return results;
}

편집: 제안 사항에 따라 코드를 대부분 수정했지만 여전히 동일한 문제가 있습니다.아래는 동일한 문제가 있는 코드의 단순화된 부분입니다.

private boolean attemptLogin(String uName, String pWord) {

    ResultSet results;
    try{
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        connection =DriverManager.getConnection(connectionString,user,password);
        PreparedStatement statement = connection.prepareStatement("select username from users where username='testuser'");
        results = statement.executeQuery();
        if(results != null && results.next()){
            System.out.println("found a result");
            statement.close();
            return true;
        }
        System.out.println("did not find a result");
        statement.close();
        return false;
    }catch(SQLException e){
        e.printStackTrace();
        return false;
    }

}

또한 해당 오류의 원인을 제거하기 위해 현재로서는 쿼리를 하드 코딩했습니다.이전과 동일한 문제(모든 쿼리에서 발생함)디버거는 모든 개체가 인스턴스화되고 스택 추적이 인쇄되지 않는 것을 표시합니다.또한 다른 프로젝트에서 동일한 코드(및 이전에 나열된 더 복잡한 코드)를 사용할 수 있습니다.

저는 제가 가지고 있는 동시 연결 수(콘솔용 연결 수, Java용 연결 수)가 멍청한 Oracle이 마음에 들지 않는다는 것을 알게 되었습니다.유감스럽게도 서버가 제 통제하에 있지 않아서 제가 처리해야 할 것 같습니다.Oracle이 더 나은 응답을 제공할 것이라고 생각할 수 있습니다.대신 빈 결과 집합만 반환했습니다.

답변 감사합니다.

edit 이 질문을 받고 답변을 받은 이후로 많은 사람들이 근본적인 원인이 사용 중인 커밋/트랜잭션 설정과 관련이 있다고 지적했습니다.추가 힌트와 가능한 해결 방법은 다른 답변을 참조하십시오.

코드에 몇 가지 함정이 있습니다. 문제가 발생할 수 있는 곳이 몇 군데 있습니다.

첫째, 정규문 사용입니다.SQL 주입에 문제가 없도록 준비된 문을 사용합니다.

대신에

statement = connection.createStatement();

사용하다

statement = connection.prepareStatement(String sql);

이것으로, 당신의 질문은

"select distinct group_name From group_members where username= ?"

사용자 이름을 설정합니다.

 statement.setString(1, username);

다음으로, 나는 당신의 사용을 좋아하지 않습니다.myDB이면. 만약 결과가null당신은 그것에 대해 어떠한 오류도 확인하지 않고 있습니다.public List<InterestGroup> getGroups()방법.

public void sendQuery(String query)내가 보기엔 그래야 하지 않는 것 같습니다.void하지만 그것은 a를 반환해야 합니다.ResultSet또한, 인터넷에서 JDBC 예외 처리를 수행하는 적절한 방법을 검색합니다.

또한 다음 행도 있습니다.

new InterestGroup(results.getString("group_name"), myDB)

당신은 왜당은을 가지고 ?myDB매개 변수로?

더 추가하는 것이 좋습니다.System.out.println문제가 발생할 수 있는 부분을 확인할 수 있도록 코드의 문을 표시합니다.

저도 마찬가지였습니다.SQL Developer를 사용하여 데이터베이스에 테스트 데이터를 삽입하고 JDBC를 사용하여 테스트 데이터를 읽고 있었습니다.하지만 제가 얻은 것은 빈 결과 세트였습니다.열 이름과 모든 것을 알 수 있었지만 데이터를 읽는 데 문제가 있었습니다.앞서 dp3에서 지적했듯이 SQL Developer IDE에서 연결을 끊고 종료 시 Commit을 요청했습니다.

Voila! insert 명령을 사용하여 데이터베이스를 변경하지 않은 것이 문제였습니다.

SQL Developer의 경우 기본 설정 > 데이터베이스 > 고급 > 자동 커밋에 있습니다.

이것으로 저의 문제가 해결되었습니다.

java.sql.connection에서는 연결을 만든 후 다음 메서드를 호출해야 합니다.

conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);

아마도 오라클에도 비슷한 방법이 있을 것입니다.

가장 일반적인 것은 쿼리에 여러 개의 문이 있는 것입니다.

desc table;
select * from sometable where etc.;

결과를 반환하지 않는 문의 경우 다른 구문을 사용해야 합니다.이 경우에도 고객이 질식할 수 있습니다.

select * from sometable where whatever;
select * from sometable where something else;

두 개의 동일한 모양의 결과 세트가 클라이언트에 비프를 발생시킵니다.

과거에 코드에서 다음과 같은 유사한 문제가 있었습니다.

querystr = "your sql select query string"

resultset = statement.executeQuery(querystr)

while (resultset.next())
{
//do something with the data. 
//if you do something fairly involved in this block (sequentially, in the same thread)
//such as calling a function that acts on the data returned from the resultset etc.
//it causes the resultset fetch to wait long enough for resultset.next() to 
//unexpectedly return null in the middle of everything
}

이 상황에서 제가 한 일은 resultset.next()에 최소 대기 시간을 두고 모든 데이터를 로컬 메모리 데이터 구조로 로드하는 것이었습니다.그런 다음, 저는 결과 집합을 우아하게 닫은 후 로컬 데이터 구조의 데이터에 대해 제가 해야 할 일은 무엇이든 했습니다.이 동작은 윈도우즈 XP에서 Unix 백엔드/JDK 1.6.0_22 클라이언트의 Oracle 10에서 발생했습니다.

이게 도움이 되길 바랍니다.

그런 다음 데이터베이스에서 쿼리(디버거에서 직접 복사)를 두 번 확인하여 데이터가 반환되는지 확인했습니다.

저는 이 문제를 가진 엔지니어들이 제 앞에서 이 검증을 시연하도록 했습니다.프로그램에 있는 하나의 데이터베이스 계정과 대화형 SQL 셸에 있는 다른 데이터베이스 계정으로 로그인한 것으로 나타났습니다.[Oracle 8이었습니다.]

네, 저도 작전과 같은 문제가 있었습니다.동일한 사용자의 데이터베이스에 대해 두 개 이상의 열린 연결이 있을 때 발생합니다.예를 들어 SQL Developer의 연결 하나와 Java의 연결 하나가 있습니다.결과는 항상 빈 결과 집합입니다.

편집: 또한 절차를 실행하거나 데이터베이스에 삽입할 때 트랜잭션을 커밋하지 않을 때 발생합니다.

결과 집합을 반복할 때까지 연결 및 문 Object가 활성화되어 있는지 확인하십시오. 때로는 알지 못하는 사이에 닫힐 수도 있습니다.

테이블이 커밋되지 않은 상태일 수 있습니다.새 레코드를 삽입한 다음 SQL 실행 명령 창에서 커밋하고 코드를 실행합니다.

나는 plsql 클라이언트를 사용하여 서버에 로그인했고 코드에서 연결을 시도하는 동안.

연결을 성공적으로 완료했지만 결과 집합에 레코드가 없습니다.

서버에서 로그아웃한 후에만 결과 집합이 채워졌습니다.

@dps3에 동의합니다. Oracle은 적절한 오류/경고 메시지를 제공해야 합니다.

저에게 문제는 기본 키 열을 만들 때 NULL ENABLE이 없었다는 것입니다.에 있는 것처럼

CREATE TABLE SYSTEM_SETTINGS  ( 
  SYSTEM_SETTING_ID NUMBER(9,0) NOT NULL ENABLE, 
    "KEY" VARCHAR2(50 BYTE), 
    "VALUE" VARCHAR2(128 BYTE),
     CONSTRAINT "PK_SYSTEM_SETTINGS" PRIMARY KEY (SYSTEM_SETTING_ID)) 
TABLESPACE USERS;

내가 그것 없이 테이블을 다시 만들었을 때

CREATE TABLE SYSTEM_SETTINGS  ( 
  SYSTEM_SETTING_ID NUMBER(9,0), 
    "KEY" VARCHAR2(50 BYTE), 
    "VALUE" VARCHAR2(128 BYTE),
     CONSTRAINT "PK_SYSTEM_SETTINGS" PRIMARY KEY (SYSTEM_SETTING_ID)) 
TABLESPACE USERS;

JDBC를 통해 작동하기 시작했습니다.나는 jdbc 드라이버에 ojdbc6.jar를 사용하고 있습니다.

resultSet은 쿼리에 대한 행 값을 가져와야 하는데도 false를 반환하고 rs.next()는 쿼리에 대한 SQL 터미널에서 커밋을 작성하지 않았을 수 있기 때문에 false를 반환합니다.이렇게 하면 gs.next()가 True로 표시됩니다.

입력한 데이터가 테이블에 저장되지 않기 때문입니다.표에 값이 삽입되면 표를 커밋합니다.이는 파일 시스템의 저장 옵션과 유사하게 작동합니다.

저도 마찬가지였습니다.SQL Developer를 사용하여 데이터베이스에 테스트 데이터를 삽입하고 JDBC를 사용하여 테스트 데이터를 읽고 있었습니다.하지만 제가 얻은 것은 빈 결과 세트였습니다.열 이름과 모든 것을 알 수 있었지만 데이터를 읽는 데 문제가 있었습니다.앞서 dp3에서 지적했듯이 SQL Developer IDE에서 연결을 끊고 종료 시 Commit을 요청했습니다.

Voila! insert 명령을 사용하여 데이터베이스를 변경하지 않은 것이 문제였습니다.

SQL Developer의 경우 기본 설정 > 데이터베이스 > 고급 > 자동 커밋에 있습니다.

이것으로 저의 문제가 해결되었습니다.

제 경우에는 SQL developer에서 작동했던 쿼리가 JAVA에서 작동하지 않았습니다.

*select * from table where process_date like '2014-08-06%'* (worked in sql developer)

formating process_date to char는 JAVA에서 작동하는 데 도움이 되었습니다.

*select * from table where to_char(process_date) = '06-AUG-14'*

언급URL : https://stackoverflow.com/questions/4343078/jdbc-returning-empty-result-set

반응형