2012-04-03 6 views
5

Ho una domanda come segue:Impossibile trovare una chiave generata in Java utilizzando getGeneratedKeys di PreparedStatement()

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

ho poi fare un PreparedStatement come questo:

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

Durante l'esecuzione e il debug a quel punto di debug, vedo che il mio ResultSet ha solo una chiave, una stringa - non come l'ID che mi aspetto affatto. Quando si controlla il database, tutto funziona correttamente, l'ID viene inserito e tutto. C'è qualcosa in getGeneratedKeys(); questo mi confonde.

Cosa sto sbagliando?

Grazie in anticipo

+2

Non si sta utilizzando 'chiavi generate', si sono solo utilizzando un generatore nella vostra INSERT dichiarazione. 'getGeneratedKeys()' è usato per restituire le chiavi generate dal DB come parte di INSERT (da una colonna Identity o attraverso un trigger). –

risposta

8

Mi aspetto che la "chiave" che si sta recuperando che assomigli ad una stringa sia la ROWID - questa è l'unica chiave che il database sta generando direttamente. Dovresti essere in grado di cambiarlo per recuperare la colonna id (probabilmente è necessaria una versione moderatamente recente del driver 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 
} 

Si potrebbe anche modificare la tua ricerca per aggiungere in modo esplicito il RETURNING clausola di

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

Grazie. Ho optato per la tua prima opzione per includere generateColonne. In effetti, il mio ResultSet mi ha dato una riga che non ho capito, ma ora che passo lungo la stringa [] {"id"} restituisce l'id appena generato. – arnehehe

1

Se questo non funziona, il problema potrebbe essere con sequence.nextval. Sembra che se lo stai usando, non stai tecnologicamente autogenerando la chiave

1

Sono abbastanza sicuro che getGeneratedKeys non restituirà il valore di una chiave inizializzata con il valore successivo di una sequenza. Infatti, in questo caso, il database non genera la chiave di per sé (come con una colonna di incremento automatico).

Se volete sapere la chiave generata, quindi eseguire una prima query:

select sequence.nextval from dual 

e quindi utilizzare il risultato di questa prima query per eseguire la vostra dichiarazione preparata:

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

penso questo:

pStatement.setString('blabla'); 

dovrebbe essere:

pStatement.setString(1, 'blabla'); 

Spero che aiuti.

+0

Scusa, hai ragione. È colpa mia se non copio il mio codice qui incollato ma provando a digitare l'esempio in termini più generali per rendere il codice più facilmente leggibile. Nel mio codice, tuttavia, l'ho fatto correttamente. Quindi, mentre sei corretto, questo non è il problema con cui sto lottando. Ho modificato il mio post. – arnehehe

+0

@come hai ragione, puoi compilare il tuo codice in modo che non sia l'errore. Colpa mia. –

0

Il codice contiene un errore: Dal momento che si sta utilizzando PreparedStatement, si dovrebbe usare la propria RETURN_GENERATED_KEYS costante:

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

La funzione getGeneratedKeys() deve essere eseguita senza problemi e dovresti essere in grado di ottenere le chiavi generate in la variabile ResultSet.

In questo modo non è necessario specificare alcun nome per la riga (come suggerisce la soluzione Justin, che è piuttosto buona).Hai solo bisogno di specificare il nome di fila se si accede alle chiavi recuperati utilizzando:

id = rs.getInt("id_row_name"); 

invece di:

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