ORA-01882本质是客户端时区名不被识别,因老JDK或旧时区文件缺失Asia/Shanghai定义,导致TimeZone.getTimeZone("Asia/Shanghai")返回null或GMT;需改用-Duser.timezone=GMT%2B8或Asia/Chongqing,启用oracle.jdbc.timezoneAsRegion=true,并确保Docker含tzdata、NLS_NUMERIC_CHARACTERS一致。

ORA-01882 不是配置没对,而是客户端根本“不认识”你写的时区名 —— Asia/Shanghai 在老 JDK 或旧版 Oracle 时区文件里压根不存在,TimeZone.getTimeZone("Asia/Shanghai") 返回 null 或 GMT,驱动一构造 TIMESTAMP WITH TIME ZONE 字面量就崩。
Java 启动参数别硬写 Asia/Shanghai
老 JDK(如 8u60 及更早)自带的 tzdb.dat 没收录 Asia/Shanghai,即使 export TZ=Asia/Shanghai 也白搭。
- 优先改用 JVM 能稳定识别的等效值:
-Duser.timezone=GMT%2B8或-Duser.timezone=Asia/Chongqing(后者在 JDK 7u79/8u60 中兼容性更好) - 绝对避免同时设
-Duser.timezone=GMT%2B8和 JDBC 连接串里oracle.jdbc.timezoneAsRegion=true—— 前者会覆盖后者,导致区域名解析被跳过 - 若必须用
Asia/Shanghai,JDK 至少升到 8u181 或 JDK 11+(内置 tzdb v2018a 及以后)
JDBC 连接串必须启用 oracle.jdbc.timezoneAsRegion=true
serverTimezone 是 MySQL 参数,Oracle JDBC 驱动完全忽略它 —— 写了不仅无效,还可能干扰真实配置。
- 连接串中显式加上:
jdbc:oracle:thin:@host:port:SID?oracle.jdbc.timezoneAsRegion=true - 若用
connectionProperties方式(如 Spring Boot),写成:oracle.jdbc.timezoneAsRegion=true;oracle.jdbc.useFetchSizeWithLongColumn=true - 验证是否生效:连上后执行
SELECT SESSIONTIMEZONE FROM DUAL,结果必须是Asia/Shanghai这类区域名,而不是+08:00
Docker 容器里缺 tzdata 包是高频雷区
Alpine 或精简镜像默认不带完整时区数据,TZ=Asia/Shanghai 设置后 /usr/share/zoneinfo/Asia/Shanghai 文件根本不存在。
- Linux 宿主机上跑
ls -l /usr/share/zoneinfo/Asia/Shanghai看是否存在;容器内执行同样命令,大概率报错 “No such file or directory” - 修复方式(以 Alpine 为例):
apk add --no-cache tzdata,再cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime - 别依赖
ENV TZ=Asia/Shanghai—— 它只设环境变量,不保证文件存在;必须确保/usr/share/zoneinfo/下有对应软链或文件
别漏查隐藏的 NLS_NUMERIC_CHARACTERS
这个参数和时区八竿子打不着,但在 DBLink 场景下会意外触发 ORA-01882 —— 当客户端 NLS 设置为 '.,'(点作小数点、逗号作千分位),而服务端是 ',.',Oracle 解析跨库 TIMESTAMP 字面量时内部格式转换失败,最终 fallback 到时区解析环节并报错。
- 检查当前会话:
SELECT * FROM NLS_SESSION_PARAMETERS WHERE PARAMETER = 'NLS_NUMERIC_CHARACTERS'; - 临时修复:
ALTER SESSION SET NLS_NUMERIC_CHARACTERS = '.,'; - 根治:在 JDBC 连接串加
sessionVariables=NLS_NUMERIC_CHARACTERS='.,'(注意:此参数仅 ojdbc8+ 支持,ojdbc6 不认)
最麻烦的不是找不到解法,而是问题常由多个条件叠加触发:JDK 版本 + ojdbc 版本 + 时区文件版本 + 容器基础镜像 + NLS 参数,任意一环不对都可能让 Asia/Shanghai 变成 “未找到的区域”。先抓一个变量隔离验证,别一上来就全量改配置。


















