我遇到了一个奇怪的情况。有人可以解释为什么时间戳和时间戳之间的比较行为如下(它取决于会话时区...)。此外,在所有情况下,输出值都相同。 看起来时间戳会从会话中继承时区以进行比较,但是对于打印它不是吗?
查询:
alter session set time_zone = '-6:0';
select cast(systimestamp as timestamp), systimestamp, case when cast(systimestamp as timestamp) < systimestamp then 'timestamp < systm' else 'timestamp >= systm' end as cmp from dual;
alter session set time_zone = '1:0';
select cast(systimestamp as timestamp), systimestamp, case when cast(systimestamp as timestamp) < systimestamp then 'timestamp < systm' else 'timestamp >= systm' end as cmp from dual;
输出:
CAST(SYSTIMESTAMPASTIMESTAMP) SYSTIMESTAMP CMP
----------------------------- ----------------------------------- ------------------
14/02/06 21:22:05,319973000 14/02/06 21:22:05,319973000 -06:00 timestamp >= systm
session SET altered.
CAST(SYSTIMESTAMPASTIMESTAMP) SYSTIMESTAMP CMP
----------------------------- ----------------------------------- ------------------
14/02/06 21:22:06,057183000 14/02/06 21:22:06,057183000 -06:00 timestamp < systm
数据库位于-6时区。 Oracle Database 11g企业版11.2.0.3.0版 - 64位生产
答案 0 :(得分:1)
看看这个: https://docs.oracle.com/cd/B12037_01/server.101/b10749/ch4datet.htm#1006334
比较日期和时间戳值时,Oracle会在进行比较之前将数据转换为更精确的数据类型。例如,如果将TIMESTAMP与TIME ZONE数据类型的数据与TIMESTAMP数据类型的数据进行比较,Oracle会使用会话时区将TIMESTAMP数据转换为TIMESTAMP WITH TIME ZONE。 转换日期和时间戳数据的优先顺序如下: 1.日期 2. TIMESTAMP 3.具有当地时区的TIMESTAMP 4.时区的时间戳 对于任何一对数据类型,Oracle会将前面列表中数字较小的数据类型转换为数字较大的数据类型。
答案 1 :(得分:0)
SYSTIMESTAMP
返回TIMESTAMP WITH TIME ZONE
数据类型。看起来Oracle将TIMESTAMP
转换为TIMESTAMP WITH TIME ZONE
数据类型进行比较,实际上Oracle执行此操作:
SELECT
CASE
WHEN CAST(CAST(SYSTIMESTAMP AS TIMESTAMP) AS TIMESTAMP WITH TIME ZONE) < SYSTIMESTAMP
THEN 'timestamp < systm'
ELSE 'timestamp >= systm'
END AS cmp
FROM dual;
对于转换它需要SESSION时区,您可以使用此查询进行检查:
SELECT
EXTRACT(TIMEZONE_HOUR FROM CAST(CAST(SYSTIMESTAMP AS TIMESTAMP) AS TIMESTAMP WITH TIME ZONE)) AS TZ_HOUR
FROM dual;
你可以讨论这是否有意义。要获得正确的转换,最好使用FROM_TZ
函数,然后由您控制。 SYSTIMESTAMP
在DB时区中返回时间戳,因此正确的语句将是这个:
SELECT FROM_TZ(LOCALTIMESTAMP, DBTIMEZONE), SYSTIMESTAMP,
CASE FROM_TZ(LOCALTIMESTAMP, DBTIMEZONE) < SYSTIMESTAMP THEN
...