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

Spark SQL 2.4.1搭配ojdbc14.jar时日期作为上下界抛数字格式异常

Spark JDBC读取Oracle日期分区列时NumberFormatException问题解决

我之前也碰到过类似的情况——本地IDE跑完全正常,一提交到Spark集群就抛出数字格式错误,核心原因是Spark JDBC的lowerBound和upperBound参数默认会按数值类型解析,当你的分区列是日期类型时,集群环境的Spark版本或JDBC驱动没有正确识别日期格式,反而把日期字符串当成Long类型去解析,自然就报错了。

错误根源分析

从错误栈能看到,Spark在JDBCOptions.scala里尝试把lowerBound的字符串"2002-03-31"转成Long类型,这说明它没有把这个值当成日期处理,而是默认按数值型分区列的逻辑来解析了。本地能跑可能是因为你的本地Spark版本较新(比如Spark 3.x+),或者驱动版本已经支持日期类型的分区参数解析,而集群的Spark版本偏旧,没有这个兼容逻辑。

正确的修复方案

这里给你两个实用的解决办法,根据你的场景选就行:

方案1:将日期转换为数值型时间戳传入

把lowerBound和upperBound换成对应日期的毫秒级时间戳(Long类型数值),同时确保分区列的比较逻辑也用时间戳。比如"2002-03-31"对应的时间戳是1017590400000,"2019-05-01"是1556688000000,修改后的代码如下:

Dataset<Row> ss = ora_df_reader 
    .option("inferSchema", true) 
    .option("schema","schema1") 
    .option("numPartitions", 20)
    .option("partitionColumn", "CAST(INSERTION_DATE AS TIMESTAMP)")
    .option("sessionInitStatement", "ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD'")
    .option("oracle.jdbc.mapDateToTimestamp","false")
    .option("lowerBound", "1017590400000") 
    .option("upperBound", "1556688000000")
    .option("dbtable", "select * from schema1.modal_vals") 
    .load();

方案2:将日期转成YYYYMMDD格式的数值列(更直观)

在查询里把日期列转成YYYYMMDD格式的数字(比如20020331),用这个数值列作为分区列,同时lowerBound和upperBound用对应的数字,这样Spark就能正确按数值解析了,代码示例:

Dataset<Row> ss = ora_df_reader 
    .option("inferSchema", true) 
    .option("schema","schema1") 
    .option("numPartitions", 20)
    .option("partitionColumn", "TO_NUMBER(TO_CHAR(INSERTION_DATE, 'YYYYMMDD'))")
    .option("sessionInitStatement", "ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD'")
    .option("oracle.jdbc.mapDateToTimestamp","false")
    .option("lowerBound", "20020331") 
    .option("upperBound", "20190501")
    .option("dbtable", "select *, TO_NUMBER(TO_CHAR(INSERTION_DATE, 'YYYYMMDD')) as INSERTION_DATE_NUM from schema1.modal_vals") 
    .load();

额外注意点

  • 确保本地和集群的Spark版本、Oracle JDBC驱动版本完全一致,版本差异是这类环境不一致问题的常见诱因。
  • 如果你的集群是Spark 3.x版本,也可以尝试显式指定dateFormat参数的同时,把partitionColumn的类型明确为日期,但这个方法在部分Oracle驱动版本下可能不生效,不如上面两个方案稳妥。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:38:43