2015-06-05 18 views
5

Ho uno strano problema con Dbutils, sto cercando di eseguire un aggiornamento con parametri sql, sto fornendo un numero corretto di argomenti, ma dbutils sta modificando il nome della colonna timestamp cambiando il nome di modificarloApache Dbutils che modifica il nome della colonna nell'aggiornamento Sql

quando timestamp columnname è un alfabeto

java.sql.SQLException: numero errato di parametri: attesi 4, è stato dato 5 Query: UPDATE WEATHER_2 SET TEMPO =? , O = TO_TIMESTAMP (?, 'YYYY-MM-DD HH24: MI: SS.FF'), HUMIDITY =? , TEMP =? WHERE ID =? Parametri: [804, 2015/06/05 17: 21: 05.809, 16.0, 25.15, 1347927]

quando timestamp columnname è normal..it sarà ommit il secondo alfabeto

java. sql.SQLException: ORA-00904: "OSTIME": identificatore non valido Query: UPDATE WEATHER_2 SET WEATHER =? , OBSTIME = TO_TIMESTAMP (?, 'YYYY-MM-DD HH24: MI: SS.FF'), HUMIDITY =? , TEMP =? WHERE ID =? Parametri: [804, 2015/06/05 17: 27: 46,139, 16.0, 25.15, 1.347.927]

potrebbe questa essere una cosa database? Anche questo sta accadendo solo con colonne il cui tipo è Data o Timestamp.

+0

File un problema con My Oracle Support. –

risposta

6

Ho avuto un problema simile. Penso che sia un bug nel driver Oracle JDBC 7 (ojdbc7.jar). Il bug potrebbe essere nel metodo PreparedStatement.getParameterMetaData.

Questo metodo è utilizzato internamente da Apache DBUtils. Quindi non sarebbe un bug di DBUtils, ma un bug dal driver JDBC Oracle distribuito con Oracle 12c.

Same Query funzionerà correttamente se si utilizza il driver ojdbc6.jar Oracle 11g. Almeno ha funzionato per me.

Se si desidera vedere come la Query viene elaborata erroneamente dal driver Oracle ojdbc7.jar, è possibile utilizzare il metodo principale incluso nella classe oracle.jdbc.driver.OracleParameterMetaDataParser. Prova questo:

java -classpath ojdbc7.jar oracle.jdbc.driver.OracleParameterMetaDataParser "SQL QUI"

esempio

java -classpath ojdbc7.jar oracle.jdbc.driver.OracleParameterMetaDataParser "UPDATE persona ambientato LASTNAME = ?, FIRSTNAME =? WHERE PersonID =?"

L'uscita è la tua frase SQL analizzato e convertito in una query SQL che viene utilizzato internamente dal driver di identificare i tipi di dati dei parametri:

SQL: UPDATE persona ambientato LASTNAME = 1, Nome =: 2 DOVE personID =: 3 SqlKind: UPDATE, parametro Count = 3 SQL Parametro: SELECT COGNOME, F, personID da persona

Ma come si può vedere nel campione, il NOME è erroneamente analizzato solo come "F".

Utilizzando una delle query che hai inserito nella tua domanda, il risultato è che uno dei parametri scompare ... quindi il parser dice parametri "5" ma la query interna utilizzata per ottenere i tipi di dati ha effettivamente solo "4" "(HUMIDITY è passato da SELECT).

java -classpath ojdbc7.jar oracle.jdbc.driver.OracleParameterMetaDataParser "UPDATE WEATHER_2 SET TEMPO =, OBSTIME = TO_TIMESTAMP (, 'YYYY-MM-DD HH24: MI: ss.ff'?)?, HUMIDITY =?, TEMP =? WHERE ID =? "

uscita:

SQL: UPDATE WEATHER_2 SET TEMPO = 1, OBSTIME = TO_TIMESTAMP (: 2 , 'YYYY-MM-DD HH24: MI: ss.ff'), UMIDITA '= : 3, TEMP =: 4 WHERE ID =: 5
SqlKind: UPDATE, Count Parametro = 5
Parametro SQL: SELECT METEO, OBSTIME, TEMP, ID dA WEATHER_2

Come Fixit? Non ho idea, ma come ho detto sopra, usando il driver Oracle 11g ojdbc6.jar, funziona la stessa query (anche collegandomi con un database Oracle 12c ...).

Il comportamento è piuttosto casuale. Sembra che dipenda dalla prima lettera della colonna utilizzata in UPDATE. Se inizia con F e H fallisce sempre, ma non so se ci sono altre condizioni.

+0

Ci sono almeno altri 2 bug già aperti a Oracle in merito ai problemi su PreparedStatement.getParameterMetadata: http://stackoverflow.com/a/25431409/3371541 –

+0

oracle 12.1.0.1.0 jdbc oracle.jdbc.driver.OracleParameterMetaDataParser suck! – qxo

0

oracle 12.1.0.1.0 jdbc oracle.jdbc.driver.OracleParameterMetaDataParser succhia!

sulla mia prova:

oracle.jdbc.driver.OracleParameterMetaDataParser.main (new String [] { "aggiornamento set di test ORDX = ?, A123 = ?, FABCDEFG = dove A2C =?"})

==>

SQL: prova aggiornamento impostato ORDX = 1, A123 =: 2, FABCDEFG =: 3 dove A2C =: 4 SqlKind: uPDATE, conteggio dei parametri = 4 Parametro SQL: SELECT OX, A23, F, AC FROM test

inizio campo con "O" troncerà 1-2 caratteri

campo iniziano con "F" tagliare tutto

inizio campo con "A" tagliare 1 carattere

su Oralce 12.1.0.2.0 hanno ancora il problema: Avviare campo con "F" tagliare tutto

http://www.oracle.com/technetwork/database/features/jdbc/default-2280470.html

0

ho incontrato lo stesso problema, utilizzando DBUtils e da ojdbc6 aggiornamento a ojdbc7. Quindi sono consapevole che si tratta di un bug sul parametro, quindi lo compilo da solo. Come questo:

update():

 Connection conn = dataSource.getConnection(); 
     PreparedStatement ps = conn.prepareStatement(sql.toUpperCase()); 
     this.fillStatement(ps, param); 
     int rs = ps.executeUpdate(); 
     ps.close(); 
     conn.close(); 

fillStatement():

private void fillStatement(PreparedStatement stmt, Object... params) throws SQLException { 
    int i = 1; 
    for (Object o: params){ 
     fill(stmt, i, o); 
     i ++; 
    } 
} 

private void fill(PreparedStatement stmt, int index, Object param) throws SQLException { 
    if (param == null) { 
     stmt.setObject(index, null); 
    } else if (param instanceof String) { 
     stmt.setString(index, (String) param); 
    } else if (param instanceof Boolean) { 
     stmt.setBoolean(index, (Boolean) param); 
    } else if (param instanceof Integer) { 
     stmt.setInt(index, (Integer) param); 
    } else if (param instanceof Long) { 
     stmt.setLong(index, (Long) param); 
    } else if (param instanceof Double) { 
     stmt.setDouble(index, (Double) param); 
    } else if (param instanceof Float) { 
     stmt.setFloat(index, (Float) param); 
    } else if (param instanceof Short) { 
     stmt.setShort(index, (Short) param); 
    } else if (param instanceof Clob) { 
     stmt.setClob(index, (Clob) param); 
    } else if (param instanceof Blob) { 
     stmt.setBlob(index, (Blob) param); 
    } else if (param instanceof java.sql.Timestamp) { 
     stmt.setTimestamp(index, (java.sql.Timestamp) param); 
    } else if (param instanceof BigDecimal) { 
     stmt.setBigDecimal(index, (BigDecimal) param); 
    }else if (param instanceof java.sql.Time) { 
     stmt.setTime(index, (java.sql.Time) param); 
    } else if (param instanceof java.sql.Date) { 
     stmt.setDate(index, (java.sql.Date) param); 
    } else if (param instanceof Date) { 
     stmt.setDate(index, new java.sql.Date(((Date) param).getTime())); 
    } else { 
     stmt.setObject(index, param); 
    } 
} 
Problemi correlati