You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle数据库DATE列调用ResultSet.getObject报Invalid Column Type异常

Oracle DATE列使用JdbcTemplate获取返回值时触发"Invalid Column Type"异常解决方案

环境信息

  • JDK: temurin-jdk8u412-b08
  • Spring Boot: 2.7.18

问题说明

使用Spring的JdbcTemplate.update(final PreparedStatementCreator psc, final KeyHolder generatedKeyHolder)方法执行插入操作时,针对Oracle数据库的DATE列调用ResultSet.getObject(int columnIndex)会抛出"Invalid Column Type" SQLException。已升级Spring Boot版本,问题未解决。

执行的SQL语句:

insert into SAMPLE_TBL (ID, A_COL, B_COL, C_DATE) values (?,?,?,?) RETURNING (ID, C_DATE)

传入参数:

  • 1234
  • 1234
  • 1234
  • "2024-08-05T01:22:16.229"

解决办法

核心原因

Oracle DATE类型仅存储日期和时分秒(无毫秒精度),Java端传入带毫秒的时间字符串后,RETURNING子句返回的DATE列在ResultSet中的类型映射与getObject()的默认处理不匹配,导致驱动抛出类型错误。

具体操作

  1. 明确参数的SQL类型
    设置PreparedStatement参数时,为DATE列指定准确的SQL类型,避免驱动自动推断错误:

    // 保留毫秒精度用Timestamp
    ps.setTimestamp(4, Timestamp.valueOf("2024-08-05T01:22:16.229"));
    // 仅需日期部分用Date
    ps.setDate(4, Date.valueOf(LocalDate.parse("2024-08-05T01:22:16.229", DateTimeFormatter.ISO_DATE_TIME)));
    
  2. 使用对应类型的方法获取返回值
    避免直接调用getObject(),针对DATE列改用getDate()或getTimestamp():

    // 从KeyHolder中获取
    Date cDate = generatedKeyHolder.getKeys().get("C_DATE", Date.class);
    // 自定义处理ResultSet时
    Timestamp cDateTimestamp = rs.getTimestamp("C_DATE");
    
  3. 适配Oracle JDBC驱动版本
    确保使用与JDK8兼容的ojdbc8驱动,旧版本驱动可能存在DATE类型映射的bug,更新到对应版本可解决部分类型匹配问题。

  4. 调整SQL的RETURNING子句
    显式转换DATE列的返回类型为TIMESTAMP,让Java端能正常读取:

    insert into SAMPLE_TBL (ID, A_COL, B_COL, C_DATE) values (?,?,?,?) RETURNING ID, CAST(C_DATE AS TIMESTAMP)
    

内容的提问来源于stack exchange,提问作者world skills

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 02:13:22