【问题标题】:Add timezone to Oracle 'DATE' result将时区添加到 Oracle 'DATE' 结果
【发布时间】:2014-05-29 01:06:58
【问题描述】:

我正在使用客户的 Oracle 11G 数据库,其中他们有一个特定的列 x 存储为 DATE 类型(没有时区)。我碰巧通过与他们的交流知道这对他们来说是当地时间,例如America/New_York。我想查询数据库以获取此列的值,该格式采用明确的格式,例如 2013-12-14 15:12:46-0500,其他工具可以轻松正确读取。

我在 Oracle 文档中没有看到一种简单的方法来为列的值(在查询时) 注入时区,然后对其进行格式化:

SELECT TO_CHAR(FROM_TZ(TO_TIMESTAMP(x), 'America/New_York'),
               'YYYY-MM-DD HH24:MI:SSTZHTZM') AS x

但这很丑陋,每当我需要检索日期时,我不喜欢在我的查询中涂上厚厚的一层。有更好的解决方案吗?说服客户更改列类型不是一种选择。

【问题讨论】:

  • 是否可以将该翻译嵌入到一个函数中并从您的查询中调用它?

标签: oracle date


【解决方案1】:

TO_TIMESTAMP(x) 调用正在进行两次隐式转换,因此它仅在您的 NLS_DATE_FORMATNLS_TIMESTAMP_FORMAT 相似时才有效。该函数接受一个字符串参数,因此您实际上是在使用TO_TIMESTAMP(TO_CHAR(x)),并且由于您不应该依赖 NLS 设置,您应该真正将其扩展为 TO_TIMESTAMP(TO_CHAR(x, 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS')

显然,这只会让你的涂抹变得更糟,除非你按照 TrippKinetics 的建议在函数中这样做。或者您可以在视图中或使用虚拟列进行操作;但客户可能也不热衷于其中任何一个。

要完全在查询中执行此操作,您可以使用CAST 而不是TO_TIMESTAMP,这比原来的输入要好一些:

SELECT TO_CHAR(FROM_TZ(CAST(x AS TIMESTAMP), 'America/New_York'),
               'YYYY-MM-DD HH24:MI:SSTZHTZM') AS x

如果您的会话始终与数据库处于同一时区,或者您可以合理地设置它,那么您可以绕过每个查询的 FROM_TZ 部分:

ALTER SESSION SET TIME_ZONE = 'America/New_York';
SELECT TO_CHAR(CAST(x AS TIMESTAMP WITH TIME ZONE),
               'YYYY-MM-DD HH24:MI:SSTZHTZM') AS x

但您必须确保您可以/将始终更改会话。

如果你总是改变会话,这可能是设置你的 NLS_TIMESTAMP_TZ_FORMAT 的合法时间(尽管我怀疑我会因为考虑建议它而被否决!) ,这意味着您可以使用隐式转换进行显示:

ALTER SESSION SET TIME_ZONE = 'America/New_York';
ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT = 'YYYY-MM-DD HH24:MI:SSTZHTZM';
SELECT CAST(x AS TIMESTAMP WITH TIME ZONE) AS x

使用您的示例日期/时间和一个在夏季,这给出了:

X                       
-------------------------
2014-05-27 14:48:12-0400  
2013-12-14 15:12:46-0500  

更改会话后,您只需将所需的每个日期列以扩展格式包装在 CAST() 中。这仍然有点痛苦,但更易于管理。尽管使用视图或虚拟列很接近,但无法在数据库中完全透明地做到这一点。定义自己的函数或设置会话以便安全地CAST 需要更多的工作。

可以说依赖会话更改会增加一些风险、不确定性或混乱,但这是为了方便而做出的权衡。

所有这些都假设所有原始日期确实都是针对一个时区的。

【讨论】:

    猜你喜欢
    • 2010-12-12
    • 2019-01-17
    • 1970-01-01
    • 1970-01-01
    • 2020-02-03
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    • 2015-05-10
    相关资源
    最近更新 更多