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() 时的主要内容,如果未能解决你的问题,请参考以下文章

spark中的to_timestamp()函数给出空值

Pyspark:to_timestamp返回不正确的时间戳值[重复]

Pyspark to_timestamp 与时区

如何在 oracle 中的 to_timestamp() 中传递字符串变量

Postgres to_timestamp 将时区设置为 +1

Aginity Workbench for Redshift - to_timestamp 转换问题