oracle – 如何获取DBTIMEZONE和SESSIONTIMEZONE之间的数字差异?

前端之家收集整理的这篇文章主要介绍了oracle – 如何获取DBTIMEZONE和SESSIONTIMEZONE之间的数字差异?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在Oracle中是否有一种顺畅的方法获取当前时刻(当我执行调用时)SESSIONTIMEZONE和DBTIMEZONE之间的数字差异?

例如:

SELECT SESSIONTIMEZONE,DBTIMEZONE FROM DUAL;

返回:

+04:00  +07:00

所以,我需要一些函数,通过调用给定参数,我得到这两个值之间的差异.

对于上面的例子:

SELECT get_numeric_offset(SESSIONTIMEZONE,DBTIMEZONE) FROM DUAL;

将返回-3(标志是至关重要的).

当然,我可以自己编写这个函数,通过使用字符串并解析它们然后进行一些算术运算或做类似的事情(我仍然不认为这是一个非常流畅的解决方案:

SELECT (
        CAST(SYSTIMESTAMP AT TIME ZONE SESSIONTIMEZONE AS DATE) - 
        CAST(SYSTIMESTAMP AT TIME ZONE DBTIMEZONE AS DATE)
       )*24 
 FROM DUAL;

也许我错过了一些东西,Oracle实际上提供了一种计算两个给定时区之间差异的方法

关于使用SESSIONTIMEZONE的一点警告

您的第一个示例不是防弹,因为会话时区可以设置为以下任一项:

>操作系统本地时区(‘OS_TZ’)
>数据库时区(‘DB_TZ’)
>与UTC的绝对偏移量(例如,’ – 05:00′)
>时区地区名称(例如,’Europe / London’)

看看这里发生了什么:

SELECT SESSIONTIMEZONE,DBTIMEZONE FROM DUAL;

SESSIONTIMEZONE  |  DBTIMEZONE
         +04:00  |      +07:00

ALTER SESSION SET TIME_ZONE='Europe/Paris';

SELECT SESSIONTIMEZONE,DBTIMEZONE FROM DUAL;

SESSIONTIMEZONE  |  DBTIMEZONE
   Europe/Paris  |      +07:00

在你的函数中解析’Europe / Paris’字符串会变得更加困难……你应该使用TZ_OFFSET函数,以确保你总是得到相同的±HH:MM格式.

ALTER SESSION SET TIME_ZONE='Europe/Paris';

SELECT DBTIMEZONE,SESSIONTIMEZONE,TZ_OFFSET(SESSIONTIMEZONE) FROM DUAL;

 DBTIMEZONE | SESSIONTIMEZONE | TZ_OFFSET(SESSIONTIMEZONE)
     +07:00 |    Europe/Paris |                     +02:00

关于第二个解决方

我想我更喜欢你的第二个解决方案.您可以使用CURRENT_DATE而不是CAST(SYSTIMESTAMP AT TIME ZONE SESSIONTIMEZONE AS DATE)缩短它们,它们是等效的:

SELECT (
        CURRENT_DATE - 
        CAST(SYSTIMESTAMP AT TIME ZONE DBTIMEZONE AS DATE)
       )*24 
 FROM DUAL;

你在技术上甚至可以做到这一点!

SELECT (CURRENT_DATE - SYSDATE) * 24 
 FROM DUAL;

但实际上,不保证SYSDATE与DBTIMEZONE位于同一时区. SYSDATE始终绑定到底层操作系统的时区,而一旦服务器启动,就可以更改DBTIMEZONE.

虽然我分手,我还应该提醒你,某些国家/地区使用的不是整数,例如,伊朗标准时间是UTC 03:30,缅甸时间是UTC 06:30 …我不喜欢知道你是否曾经在你的生产环境中遇到过这种情况,但我希望你的查询可能会返回1.5之类的东西.

猜你在找的Oracle相关文章