2011-08-08 6 views
5

Estoy usando una instrucción SELECT para obtener datos de una tabla y luego insertarlos en otra tabla. Sin embargo, la línea "stmt.executeQuery (query);" está insertando la primera línea de la tabla y luego sale. Cuando comento esta línea, el ciclo while recorre todas las líneas imprimiéndolas. La stacktrace no muestra ningún error. ¿Por qué está pasando esto?¿Por qué la instrucción While (rs.next()) termina después de la 1ra iteración?

try{     
    String query = "SELECT * FROM "+schema_name+"."+table; 

    rs = stmt.executeQuery(query); 

    while (rs.next()) { 

     String bundle = rs.getString("BUNDLE"); 
     String project_cd = rs.getString("PROJECT_CD"); 
     String dropper = rs.getString("DROPPER"); 
     String week = rs.getString("WEEK"); 
     String drop_dt = rs.getString("DROP_DT").replace(" 00:00:00.0",""); 

     query = "INSERT INTO INDUCTION_INFO (BUNDLE, PROJECT_CD, DROPPER, WEEK, DROP_DT) " 
       + "VALUES (" 
       + bundle+"," 
       + "'"+project_cd+"'," 
       + dropper+"," 
       + week+"," 
       + "to_date('"+drop_dt+"','YYYY-MM-DD'))"; 

     System.out.println(query); 

     stmt.executeQuery(query); 
    } 
}catch(Exception e){ 
    e.printStackTrace(); 
} 
+0

Hm ... en realidad no sé si al llamar a 'executeUpdate()' en una instrucción se cierran las declaraciones anteriores 'ResultSet'. Y soy demasiado perezoso para probar eso en este momento ... –

+1

La pregunta específica ya está respondida, pero como observación: debe usar una declaración preparada y cambiar las variables de vinculación cada vez en lugar de crear una nueva inserción con los valores codificado de forma rígida. (Parece un lugar poco probable para obtener una inyección SQL, pero depende de quién puede colocar las entradas en la tabla fuente ...). Pero, ¿por qué no simplemente hacerlo de un golpe con un select-as-insert, en lugar de un bucle? –

Respuesta

24

se vuelven a usar el Statement que se utilizó para producir rs en la última línea de su bucle.

Esto cerrará el ResultSetrs. Como stated in the documentation:

Un objeto ResultSet se cierra automáticamente cuando el objeto Statement que la generó está cerrado, vuelve a ejecutar, o se utiliza para recuperar el siguiente resultado de una secuencia de varios resultados.

Necesita utilizar un segundo objeto Statement para ejecutar las instrucciones INSERT.

9

Statement objetos solo pueden hacer una cosa a la vez, por lo que cuando ejecutas ese INSERT, invalidas el ResultSet que generó. Tendrá que crear un segundo objeto Statement para realizar el INSERT.

Desde el Statement documentation: "De forma predeterminada, solo se puede abrir al mismo tiempo un objeto ResultSet por objeto Statement. Por lo tanto, si la lectura de un objeto ResultSet se intercala con la lectura de otro, cada uno debe haber sido generado por diferentes objetos de Statement. Todos los métodos de ejecución en la interfaz de Statement implícitamente cierran el objeto ResultSet actual de un statment si existe uno abierto. "

1

si usa la misma declaración, invalidará el conjunto de resultados anterior. Debe usar una instrucción diferente para realizar actualizaciones/inserciones.

1

Esto es de la documentación de Java de interfaz de Statement:

Por defecto, sólo un objeto ResultSet por objeto Statement puede estar abierto al mismo tiempo.

Así que es mejor utilizar una segunda Statement o incluso mejor un PreparedStatement.

Y para ejecutar una instrucción INSERT SQL debe usar executeUpdate() en lugar de executeQuery().

Cuestiones relacionadas