timezone-dependant systimestamp and timestamp comparison on Oracle

爷,独闯天下 提交于 2021-02-08 08:34:20

问题


I've run into a weird situation. Could someone explain why comparison between timestamp and timestamp behaves as below (it depends on session timezone...). In addition outputed values are identical in all cases. It looks like timestamp inherits timezone from the session for comparison purposes, but for printing it does not?

Queries:

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;

output:

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  

Database is in -6 timezone. Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production


回答1:


Look at this: https://docs.oracle.com/cd/B12037_01/server.101/b10749/ch4datet.htm#1006334

When you compare date and timestamp values, Oracle converts the data to the more precise datatype before doing the comparison. For example, if you compare data of TIMESTAMP WITH TIME ZONE datatype with data of TIMESTAMP datatype, Oracle converts the TIMESTAMP data to TIMESTAMP WITH TIME ZONE, using the session time zone. The order of precedence for converting date and timestamp data is as follows: 1. DATE 2. TIMESTAMP 3. TIMESTAMP WITH LOCAL TIME ZONE 4. TIMESTAMP WITH TIME ZONE For any pair of datatypes, Oracle converts the datatype that has a smaller number in the preceding list to the datatype with the larger number.




回答2:


SYSTIMESTAMP returns a TIMESTAMP WITH TIME ZONE datatype. Looks like Oracle converts the TIMESTAMP to an TIMESTAMP WITH TIME ZONE datatype for comparison, actualy Oracle performs this:

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;

For conversion it takes the SESSION Timezone, you can check it with this query:

SELECT 
    EXTRACT(TIMEZONE_HOUR FROM CAST(CAST(SYSTIMESTAMP AS TIMESTAMP) AS TIMESTAMP WITH TIME ZONE)) AS TZ_HOUR
FROM dual;

You can discuss if this makes sense or not. For a correct conversion you better use FROM_TZ function, then it is under your control. SYSTIMESTAMP returns timestamp in DB timezone, so proper statement would be this one:

SELECT FROM_TZ(LOCALTIMESTAMP, DBTIMEZONE), SYSTIMESTAMP, 
    CASE FROM_TZ(LOCALTIMESTAMP, DBTIMEZONE) < SYSTIMESTAMP THEN
    ...


来源:https://stackoverflow.com/questions/21618732/timezone-dependant-systimestamp-and-timestamp-comparison-on-oracle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!