【问题标题】:Spring JDBC lob insertion fails: Invalid column typeSpring JDBC lob插入失败:无效的列类型
【发布时间】:2012-08-13 20:12:59
【问题描述】:

代码:

                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

我什至不确定我可以添加哪些其他信息,但如果我遗漏了一些信息,我会很乐意这样做。

【问题讨论】:

  • 这会以同样的方式失败,查询只是“INSERT INTO app_role_data(app_name, xml_blob) VALUES (?,?)”
  • 请注意,Spring 3.1.1.RELEASE 也会失败。我真的不敢相信我是整个宇宙中唯一无法使用 Spring JDBC 3.x 将 CLOB 插入 Oracle 11g 数据库的人。
  • Oracle 11.2.0.2.0 JDBC 驱动程序也会失败。

标签: oracle spring-jdbc lob


【解决方案1】:

原来,execute() 采用 PreparedStatementCallback,而 update() 采用 PreparedStatementSetter。但是两者都有接受 Object 的重载,所以编译器不会抱怨。

抱怨。那是我一生中再也回不来的一天。

【讨论】:

    【解决方案2】:

    我对这里的列名有点怀疑

    您可以在MERGE 中尝试类似下面的内容

    select ? as name, ? as xml FROM dual
    

    但我也对此持怀疑态度,因为您可以拥有动态列名的方式是创建一个动态 sql 并使用 EXECUTE IMMEDIATE 执行它。

    或者可能是这样的(就 Oracle 而言不是最好的)-

    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(?, ?)",......
    

    【讨论】:

    • 即使查询只是“INSERT INTO app_role_data(app_name, xml_blob) VALUES(?,?)”,失败也是一样的
    • 你能运行desc app_role_data 并发布输出吗?我在想CLOB 列出了点问题。
    • 看起来您的列xml_blob 的类型为BLOB,而您正在使用lobCreator.setClobAsString 创建CLOB。您可以尝试使用setBlobAsBytes 创建一个blob 实例吗?然后用它代替..
    • 架构创建脚本有“create table app_role_data(app_name varchar2(64), xml_blob clob);”创建该表。
    猜你喜欢
    • 1970-01-01
    • 2021-09-04
    • 2019-03-07
    • 2021-03-01
    • 2021-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-27
    相关资源
    最近更新 更多