ORA-01857 执行 to_timestamp_tz() 时
Posted
技术标签:
【中文标题】ORA-01857 执行 to_timestamp_tz() 时【英文标题】:ORA-01857 when executing to_timestamp_tz() 【发布时间】:2016-08-04 23:14:07 【问题描述】:为什么要通过 SQLDeveloper
执行此查询以连接到我的数据库:
select to_timestamp_tz('05/22/2016 10:18:01 PDT', 'MM/DD/YYYY HH24:MI:SS TZD') from dual;
我收到以下错误:
ORA-01857: "not a valid time zone"
01857. 00000 - "not a valid time zone"
*Cause:
*Action:
但是,我可以直接从数据库所在主机上的sqlplus
执行查询而没有任何错误,得到预期的结果:
TO_TIMESTAMP_TZ('05/22/201610:18:01PDT','MM/DD/YYYYHH24:MI:SSTZD')
---------------------------------------------------------------------------
22-MAY-16 10.18.01.000000000 AM -07:00
所以,我想弄清楚我是否做错了什么。我已经读过这个错误可能是因为一个时区有多个tzabbrev
,但这并不能解释为什么在sqlplus
上正确运行查询,因为我可以在主机和主机上看到不同时间区域的多个tzabbrev
SQLDeveloper
(来自v$timezone_names
的查询)。
真正的问题是我们的应用程序使用了这个查询,所以我们注意到这个问题有时会重现,即使应用程序部署在与数据库相同的主机上。
【问题讨论】:
【参考方案1】:我在 sqldeveloper\sqldeveloper\bin\sqldeveloper.conf 中添加了 2 行新行
AddVMOption -Doracle.jdbc.timezoneAsRegion=false
AddVMOption -Duser.timezone=CET
这解决了问题。
更新
为了消除时间从标准时间切换到夏令时时边界情况的歧义,请同时使用 TZR 格式元素和相应的 TZD 格式元素
要在不更改任何 JVM 配置的情况下使您的查询正常工作,您应该提供时区区域
select to_timestamp_tz('05/22/2016 10:18:01 PDT US/Pacific', 'MM/DD/YYYY HH24:MI:SS TZD TZR') from dual;
由于您没有提供时区区域,它将获得默认区域。我们来看第一个参数'oracle.jdbc.timezoneAsRegion'。这由 jdbc 驱动程序定义如下:
CONNECTION_PROPERTY_TIMEZONE_AS_REGION
使用指定的 JVM 默认时区,而不是转换为 GMT 偏移量。默认为真。
因此,如果不定义此属性,您将强制查询使用属性“user.timezone”定义的默认时区区域。但实际上你还没有设置它。因此,解决方案是将属性“oracle.jdbc.timezoneAsRegion”设置为 false(将使用数据库当前会话时区区域)或隐式提供“user.timezone”属性
【讨论】:
嗨,Thanh,在进行更改后,您提到它有效。即使我只添加 timezoneAsRegion=false 也可以。你能再解释一下吗? 我从文档中看到修改的变量是这样的:CONNECTION_PROPERTY_TIMEZONE_AS_REGION 如果我们改变这个值,其他查询会失败吗?改变这个变量有什么影响?我正在研究该属性,但我想快速回复,以免线程死亡。以上是关于ORA-01857 执行 to_timestamp_tz() 时的主要内容,如果未能解决你的问题,请参考以下文章
Pyspark:to_timestamp返回不正确的时间戳值[重复]
如何在 oracle 中的 to_timestamp() 中传递字符串变量