2012-04-03 11 views
5

Tengo una consulta de la siguiente manera:No es posible encontrar una clave generada en Java utilizando getGeneratedKeys de PreparedStatement()

String SQL = "insert into table (id, name) values (sequence.nextval, ?)"; 

Entonces hago un PreparedStatement así:

//initiate connection, statement etc 
pStatement = connection.prepareStatement(SQL, Statement.RETURN_GENERATED_KEYS); 
pStatement.setString(1,'blabla'); 

pStatement.executeUpdate(); 
ResultSet rs = pStatement.getGeneratedKeys(); 

while (rs.next()){ 
    //debugging here to see what rs has 
} 

Al ejecutar y depurar en ese punto de depuración, veo que mi ResultSet solo tiene una clave, una cadena, no como el ID que espero en absoluto. Al revisar la base de datos, todo funciona bien, los identificadores se insertan y todo. Hay algo acerca de getGeneratedKeys(); eso me confunde.

¿Qué estoy haciendo mal?

Gracias de antemano

+2

No está utilizando 'claves generadas', usted está usando un generador en su INSERT declaración. 'getGeneratedKeys()' se usa para devolver claves generadas por el DB como parte del INSERT (por una columna de identidad o por un desencadenante). –

Respuesta

8

Espero que la "clave" que está recibiendo que parece una cadena sea ROWID - esa es la única clave que la base de datos está generando directamente. Debería poder cambiar eso para recuperar su columna id (esto probablemente requiera una versión moderadamente reciente del controlador JDBC).

//initiate connection, statement etc 
String generatedColumns[] = {"ID"}; 
pStatement = connection.prepareStatement(SQL, generatedColumns); 
pStatement.setString(1,'blabla'); 

pStatement.executeUpdate(); 
ResultSet rs = pStatement.getGeneratedKeys(); 

while (rs.next()){ 
    //debugging here to see what rs has 
} 

También podría cambiar la consulta para añadir explícitamente el RETURNING cláusula

String SQL = "insert into table (id, name) " + 
      " values (sequence.nextval, ?) " + 
      " returning id into ?"; 
+0

Gracias. He optado por su primera opción para incluir las Columnasgeneradas. De hecho, mi ResultSet primero me dio una fila que no entendí pero ahora que paso la cadena [] {"id"} devuelve la nueva ID generada. – arnehehe

1

Si esto no funciona, el problema podría ser con sequence.nextval. Parece que si está usando eso, técnicamente no está autogenerando la clave

1

Estoy bastante seguro de que getGeneratedKeys no devolverá el valor de una clave que se inicializó con el siguiente valor de una secuencia. De hecho, en este caso, la base de datos no genera la clave por sí misma (como lo haría con una columna de incremento automático).

Si desea conocer la clave generada, a continuación, ejecutar una primera consulta:

select sequence.nextval from dual 

y luego usar el resultado de esta primera consulta para ejecutar su declaración preparada:

insert into table (id, name) values (?, ?) 
1

pienso esto:

pStatement.setString('blabla'); 

debería ser:

pStatement.setString(1, 'blabla'); 

Espero que ayude.

+0

Lo sentimos, tienes razón. Esto es mi culpa por no copiar pegando mi código aquí, pero tratando de escribir el ejemplo en términos más generales para que el código sea más fácil de leer. En mi código, sin embargo, lo he hecho correctamente. Entonces, mientras estás en lo cierto, este no es el problema con el que estoy luchando. He editado mi publicación. – arnehehe

+0

@arnehehe tienes razón, puedes compilar tu código para que no sea el error. Mi culpa. –

0

su código tiene un error: Puesto que usted está utilizando PreparedStatement, debe utilizar su propio RETURN_GENERATED_KEYS constante:

pStatement = connection.prepareStatement(SQL, PreparedStatement.RETURN_GENERATED_KEYS); 

La función getGeneratedKeys() se debe ejecutar sin problemas, y debería poder obtener las claves generadas en la variable ResultSet.

De esta manera no necesita especificar ningún nombre para su fila (como sugiere la solución de Justin, que es bastante bueno).Sólo tiene que especificar su nombre de la fila si tiene acceso a las llaves recuperados usando:

id = rs.getInt("id_row_name"); 

en lugar de:

id = rs.getInt(column_number); //One column for each key retrieved. 
Cuestiones relacionadas