2012-08-13 59 views
0

的代码:弹簧JDBC高球插入失败:无效的列类型

   jdbcTemplate.update("MERGE INTO app_role_data x USING (select ? name, ? xml FROM dual) d ON (x.app_name = d.name) WHEN MATCHED THEN UPDATE SET x.xml_blob = d.xml WHEN NOT MATCHED THEN INSERT(app_name, xml_blob) VALUES(d.name, d.xml)", 
        new AbstractLobCreatingPreparedStatementCallback(lobHandler) { 
          protected void setValues(PreparedStatement ps, LobCreator lobCreator) throws SQLException { 
            ps.setString(1, appName); 
            lobCreator.setClobAsString(ps, 2, xmlBlob); 
          } 
        }); 

LobHandler接口是在上下文中注入OracleLobHandler的一个实例。

例外:

Caused by: java.sql.SQLException: Invalid column type 
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112) 
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146) 
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:208) 
    at oracle.jdbc.driver.OraclePreparedStatement.setObjectCritical(OraclePreparedStatement.java:9231) 
    at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:8812) 
    at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:9534) 
    at oracle.jdbc.driver.OraclePreparedStatement.setObject(OraclePreparedStatement.java:9517) 
    at org.springframework.jdbc.core.StatementCreatorUtils.setValue(StatementCreatorUtils.java:351) 
    at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValueInternal(StatementCreatorUtils.java:216) 
    at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValue(StatementCreatorUtils.java:144) 
    at org.springframework.jdbc.core.ArgPreparedStatementSetter.doSetValue(ArgPreparedStatementSetter.java:65) 
    at org.springframework.jdbc.core.ArgPreparedStatementSetter.setValues(ArgPreparedStatementSetter.java:46) 
    at org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:815) 
    at org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:1) 
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:586) 

这是Spring框架3.0.5.RELEASE。

我们的Oracle驱动程序相关的

 <dependency> 
     <groupId>com.oracle</groupId> 
     <artifactId>ojdbc14</artifactId> 
     <version>10.2.0.3.0</version> 
     </dependency> 

表:

SQL> desc app_role_data 
Name      Null? Type 
----------------------------------------- -------- ---------------------------- 
APP_NAME      VARCHAR2(64) 
XML_BLOB      CLOB 

我甚至不知道什么其他的信息,我可以添加,但我会很高兴,如果这样做我把东西留了下来。

+0

这与查询简单为“INSERT INTO app_role_data(app_name,xml_blob)VALUES(?,?)” – nsayer 2012-08-13 20:33:17

+0

请注意,这也会因Spring 3.1.1.RELEASE失败而失败。我真的不敢相信我是整个Universe中唯一无法使用Spring JDBC 3.x将CLOB插入Oracle 11g数据库的人。 – nsayer 2012-08-14 17:40:09

+0

使用Oracle 11.2.0.2.0 JDBC驱动程序也会失败。 – nsayer 2012-08-14 17:55:53

回答

1

事实证明,实行()需要PreparedStatementCallback,而update()方法需要一个PreparedStatementSetter。但是两者都带有Object的重载,所以编译器不会抱怨。

抱怨。那是我一生中的一天,我永远不会回来。

0

我是有点怀疑这里的列名

你可以尝试类似下面你MERGE

select ? as name, ? as xml FROM dual 

但我怀疑,太多,因为你可以有动态列的方式名称是通过创建一个动态sql并使用EXECUTE IMMEDIATE执行它。

或者可能是这样的(不是最好的甲骨文而言) -

jdbcTemplate.update("MERGE INTO app_role_data x USING dual d ON (x.app_name = ?) WHEN MATCHED THEN UPDATE SET x.xml_blob = ? WHEN NOT MATCHED THEN INSERT(app_name, xml_blob) VALUES(?, ?)",...... 
+0

即使查询只是“INSERT INTO app_role_data(app_name,xml_blob)VALUES(?,?)” – nsayer 2012-08-13 21:08:40

+0

您可以运行'desc app_role_data'并发布输出吗?我正在考虑'CLOB'列正在发生什么。 – Annjawn 2012-08-13 21:36:03

+0

看起来像你的列'xml_blob'的类型是'BLOB',并且你正在使用'lobCreator.setClobAsString'创建一个'CLOB'。你可以尝试使用'setBlobAsBytes'创建一个blob实例吗?然后用它代替。 – Annjawn 2012-08-13 21:46:59