我有一个类似的问题。我认为这是 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 这里"
例如
java -classpath ojdbc7.jar oracle.jdbc.driver.OracleParameterMetaDataParser“更新人员设置姓氏=?,名字=?哪里人=?”
输出是您的 SQL 语句解析并转换为驱动程序内部使用的 SQL 查询来识别参数数据类型:
SQL:UPDATE PERSON SET LASTNAME=:1 , FIRSTNAME=:2 WHERE PERSONID=:3 SqlKind:UPDATE, Parameter Count=3 参数 SQL: SELECT LASTNAME, F, PERSONID FROM PERSON
但正如您在示例中看到的那样,FIRSTNAME 被错误地解析为“F”。
使用您在问题中提出的查询之一,结果是其中一个参数消失了......所以解析器说“5”参数但用于获取数据类型的内部查询确实只有“4”(HUMIDITY 有从 SELECT 中消失)。
java -classpath ojdbc7.jar oracle.jdbc.driver.OracleParameterMetaDataParser "UPDATE WEATHER_2 SET WEATHER=?, OBSTIME=TO_TIMESTAMP(?,'YYYY-MM-DD HH24:MI:SS.FF'), HUMIDITY=?, TEMP=? ID=在哪里?”
输出:
SQL:UPDATE WEATHER_2 SET WEATHER=:1 , OBSTIME=TO_TIMESTAMP(:2 ,'YYYY-MM-DD HH24:MI:SS.FF') , HUMIDITY=: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总是失败,不知道还有没有其他条件。