Apache Dbutils在更新Sql

时间:2015-06-05 12:30:20

标签: sql oracle apache apache-commons-dbutils

我对Dbutils有一个奇怪的问题,我正在尝试运行参数化更新sql,我提供了正确数量的参数,但是dbutils正在修改时间戳列名称,通过更改修改它的名称

当timestamp columnname是一个字母

  

java.sql.SQLException:错误的参数数量:预期4,是   给出5个查询:UPDATE WEATHER_2 SET WEATHER =? ,   O = TO_TIMESTAMP(?,' YYYY-MM-DD HH24:MI:SS.FF'),HUMIDITY =? ,TEMP =?   在哪里ID =?参数:[804,2015-06-05 17:21:05.809,16.0,25.15,   1347927]

当timestamp columnname为normal..it将省略第二个字母

  

java.sql.SQLException:ORA-00904:" OSTIME":无效的标识符        查询:UPDATE WEATHER_2设置天气=? ,OBSTIME = TO_TIMESTAMP(?,' YYYY-MM-DD HH24:MI:SS.FF'),HUMIDITY =? ,   TEMP =?在哪里ID =?参数:[804,2015-06-05 17:27:46.139,16.0,   25.15,1347927]

这可能是数据库的事吗?此外,只有类型为Date或Timestamp的列才会发生这种情况。

3 个答案:

答案 0 :(得分:7)

我有类似的问题。我认为这是Oracle JDBC 7驱动程序(ojdbc7.jar)中的一个错误。该错误可能在PreparedStatement.getParameterMetaData方法中。

此方法由Apache DBUtils在内部使用。因此,它不会是DBUtils的错误,而是Oracle JDBC驱动程序随Oracle 12c一起发布的错误。

如果您使用Oracle 11g ojdbc6.jar驱动程序,则相同的查询可能会正常工作。它至少对我有用。

如果您想查看Oracle ojdbc7.jar驱动程序如何在内部错误地处理Query,您可以使用oracle.jdbc.driver.OracleParameterMetaDataParser类中包含的main方法。试试这个:

  

java -classpath ojdbc7.jar   oracle.jdbc.driver.OracleParameterMetaDataParser“你的SQL在这里”

e.g。

  

java -classpath ojdbc7.jar   oracle.jdbc.driver.OracleParameterMetaDataParser“更新人员设置   LASTNAME =?,FIRSTNAME =?在哪里PERSONID =?“

输出是您的SQL Sentence解析并转换为SQL查询,驱动程序在内部使用它来识别参数数据类型:

  

SQL:UPDATE PERSON SET LASTNAME =:1,FIRSTNAME =:2 WHERE PERSONID =:3   SqlKind:UPDATE,参数Count = 3参数SQL:SELECT LASTNAME,F,   来自人的人

但正如您在示例中所看到的,FIRSTNAME被错误地解析为“F”。

使用你在问题中提出的一个查询,结果是其中一个参数消失了...所以解析器说“5”参数但用于获取数据类型的内部查询确实只有“4” (HUMIDITY已经从SELECT中消失了。)

  

java -classpath ojdbc7.jar   oracle.jdbc.driver.OracleParameterMetaDataParser“更新天气设置天气=?,OBSTIME = TO_TIMESTAMP(?,'YYYY-MM-DD HH24:MI:SS.FF'),HUMIDITY =?,TEMP =?WHERE ID =?”< / p>

输出:

  

SQL:UPDATE WEATHER_2 SET WEATHER =:1,OBSTIME = TO_TIMESTAMP(:2   ,'YYYY-MM-DD HH24:MI:SS.FF'),湿度=:3,TEMP =:4 WHERE ID =:5
  SqlKind:UPDATE,参数Count = 5
  参数SQL:SELECT WEATHER,OBSTIME,TEMP,ID FROM WEATHER_2

如何修复?不知道,但正如我上面所说,使用Oracle 11g ojdbc6.jar驱动程序,同样的查询工作(甚至与Oracle 12c数据库连接......)。

行为非常随机。看起来它取决于UPDATE中使用的列的第一个字母。如果以F开头且H总是失败,但我不知道是否还有其他条件。

答案 1 :(得分:0)

oracle 12.1.0.1.0 jdbc oracle.jdbc.driver.OracleParameterMetaDataParser糟透了!

我的考试:

oracle.jdbc.driver.OracleParameterMetaDataParser.main(new String [] {“update test set ORDX =?,A123 =?,FABCDEFG =?其中A2C =?”})

==&GT;

SQL:更新测试集ORDX =:1,A123 =:2,FABCDEFG =:3其中A2C =:4   SqlKind:UPDATE,参数Count = 4   参数SQL:SELECT OX,A23,F,AC FROM test

字段以“O”开头将修剪1-2个字符

字段以“F”开头将修剪所有

字段以“A”开头将修剪1个字符

关于oralce 12.1.0.2.0仍有问题: 字段以“F”开头将修剪所有

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

答案 2 :(得分:0)

我遇到了同样的问题,使用DBUtils并从ojdbc6升级到ojdbc7。然后我知道这是参数的错误,所以我自己填写。就这样:

更新():

        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);
    }
}
相关问题