2010-12-03 14 views
14

Estoy usando JDBC para una conectividad de base de datos muy simple.JDBC devolviendo el conjunto de resultados vacío

He creado mi conexión/declaración y he ejecutado una consulta. Compruebo el objeto de consulta de la instrucción en el depurador para confirmar que está enviando una consulta adecuada. Luego comprobé dos veces la consulta (copiada directamente del depurador) en la base de datos para asegurarme de que devuelve datos. El resultado devuelto, sin embargo, da falso en .next()

¿Hay algún error común aquí que me falta?

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; 
    } 

} 

Y la clase myDB (contenedor simple que me permite colocar el código de conexión/declaración en cualquier proyecto)

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; 
} 

EDIT: Sobre la base de las sugerencias sobre todo me he renovado mi código, pero todavía tienen la el mismo problema. A continuación se muestra una porción simplificada del código que tiene el mismo problema.

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; 
    } 

} 

También he codificado la consulta realizada para eliminar esa fuente de error. Mismo problema que antes (esto sucede con todas las consultas). El depurador muestra todos los objetos que se crean instancias y no se imprimen trazas de pila. Además, puedo usar el mismo código (y el código más complicado enumerado anteriormente) en un proyecto diferente.

+1

Por favor, publique su código. Sin el código, no hay suficiente información aquí para proporcionar una respuesta. – Asaph

+0

Podría estar dentro de la función getResults, si pudieras publicar eso también ayudaría mucho. – Brains1994

+0

lo siento, agregué eso también. – dpsthree

Respuesta

18

Me di cuenta .... estúpido Oracle no me gustó el número de conexiones simultáneas que tuve (las dos, una para consola, una para Java). Desafortunadamente, el servidor no está bajo mi control, así que tendré que enfrentarlo. Usted pensaría que Oracle proporcionaría una mejor respuesta. En cambio, simplemente devolvió conjuntos de resultados vacíos. Se pidió

Gracias por las respuestas

editar Desde este/respondidas ha habido un número de personas señalado que la causa subyacente es más probable en relación con la configuración de comprometerse/de transacción en uso. Asegúrese de ver otras respuestas para obtener sugerencias adicionales y posibles soluciones.

+0

"uno para consola, uno para java", suena extraño! – craftsman

+0

Sí, me enviaron ssh'ed al equipo host para ejecutar consultas directamente para probar. Y cuando ejecuté mi programa, creó otra conexión. Lo siento si mi redacción sonaba extraña. Estaba muy somnoliento al lidiar con esto anoche. – dpsthree

+0

Me encontré con el mismo problema cuatro años después. Muchas gracias a ti, y sí estúpido Oracle. – fleetC0m

3

El más común es tener varias instrucciones en la consulta:

desc table; 
select * from sometable where etc.; 

Para los estados que no devuelven resultados, usted tiene que utilizar una construcción diferente. Incluso esto hará que el cliente se ahogue:

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

Los dos conjuntos de resultados en forma mismas serán Biff el cliente.

2

Luego verifiqué la consulta (copiada directamente desde el depurador) en la base de datos para asegurarme de que devuelve datos.

He tenido ingenieros con este problema que demuestran esta verificación en frente de mí. Resulta que iniciaron sesión con una cuenta de base de datos en el programa y con una cuenta de base de datos diferente en el shell SQL interactivo. [Esto era Oracle 8.]

+0

comprobado dos veces, sin suerte – dpsthree

1

Compruebe si la conexión y la declaración Objeto están activas hasta que itere el conjunto de resultados, algunas veces podemos cerrar inadvertidamente.

9

veo algunas trampas en su código, hay algunos lugares donde las cosas pueden salir mal:

En primer lugar, el uso de declaraciones periódicas. Use prepared statements para no tener problemas con SQL injection.

En lugar de

statement = connection.createStatement(); 

uso

statement = connection.prepareStatement(String sql); 

Con esto, su consulta se convierte

"select distinct group_name From group_members where username= ?" 

y se establece con el nombre de usuario

statement.setString(1, username); 

A continuación, no me gusta el uso de su clase myDB. ¿Qué pasa si los resultados son null? No está haciendo ningún error para verificar eso en su método public List<InterestGroup> getGroups().

public void sendQuery(String query) me parece que no debería ser void, pero debería devolver un ResultSet. Además, busque en la red las formas adecuadas de manejar excepciones JDBC.

Además, esta línea:

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

¿Por qué tienes myDB como parámetro?

Sugeriría agregar más System.out.println declaraciones en su código para que pueda ver dónde pueden salir cosas.

5

En java.sql.Connection usted debe llamar a este método después de crear la conexión:

conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); 

tal vez hay un método similar en Oracle.

2

En el pasado he tenido problemas similares en código como este:

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 
} 

Lo que hice en esta situación era que cargar todos los datos en una estructura de datos de la memoria local con mínimo de espera en resultset.next () Luego hice lo que tenía que hacer con los datos de la estructura de datos local después de cerrar con gracia el conjunto de resultados. Este comportamiento fue con Oracle 10 en Unix backend/JDK 1.6.0_22 cliente bajo Windows XP.

Espero que esto ayude.

0

En mi caso, la consulta que funcionaba en el desarrollador sql no funcionó en JAVA.

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

formateo process_date a Char ayudó a hacer que funcione en JAVA

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

Para mí, el problema era que en la creación de la columna de clave principal que tuve NO NULO ACTIVAR. Al igual que en ...

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; 

Cuando he recreado la mesa sin que, como en

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; 

Se comenzó a trabajar a través de JDBC. Estoy usando ojdbc6.jar para el controlador jdbc.

3

Me pasó lo mismo. Estaba usando SQL Developer para insertar datos de prueba en mi base de datos y lectura de prueba usando JDBC. Pero todo lo que obtuve fue un conjunto de resultados vacío. Pude obtener los nombres de las columnas y todo, pero tuve un problema con la lectura de datos. Como señaló dpsthree anteriormente, me desconecté del SQL Developer IDE y luego me pidió que confirmara al salir.

Voila! El problema era que los cambios en las bases de datos que utilizaban el comando de inserción no se habían confirmado.

Para SQL Developer esto se encuentra en Preferencias> Base de datos> Avanzado> Autocommit

Esto resolvió mi problema.

0

Sí, tuve el mismo problema que el OP. Sucede cuando tiene dos o más conexiones abiertas con la base de datos en el mismo usuario. Por ejemplo, una conexión en SQL Developer y una conexión en Java. El resultado es siempre un conjunto de resultados vacío.

EDITAR: También, me di cuenta de que sucede cuando ejecuta un procedimiento o inserta en el databse y no confirma sus transacciones.

0

Había iniciado sesión en el servidor mediante el cliente plsql y, aunque traté de conectarme desde mi código, me estaba conectando correctamente pero no había registros en el conjunto de resultados. Solo después de cerrar la sesión del servidor, se llenó el conjunto de resultados. Acepto con @dpsthree, Oracle debería proporcionar un mensaje de error/advertencia apropiado.

0

resultSet devuelve falso aunque debe obtener valores de fila para la consulta y rs.next() da falso porque es posible que no haya escrito commit; en su terminal sql para la consulta. Después de hacer esto obtendrás rs.next() como True.

Cuestiones relacionadas