Oracle отметка времени и интервал - PullRequest
0 голосов
/ 11 марта 2020

У меня есть требование получать записи из таблицы systimestamp > LAST_UPDATE_TS + 5 minutes interval

Не могли бы вы помочь с запросом?

ORACLE DB - 11G Version.

Я пробовал это, как показано ниже, но не работает как ожидается.

SYSTIMESTAMP   : 11-MAR-20 06.06.00.070695 AM -05:00
LAST_UPDATE_TS : 11-MAR-20 06.05.50.781167 AM

После применения этого условия, systimestamp > LAST_UPDATE_TS + INTERVAL '5' MINUTE, я ожидаю, что данные не должны возвращаться, но все же я получаю строки, которые не удовлетворяют условию.

Ответы [ 4 ]

1 голос
/ 11 марта 2020

SYSTIMESTAMP возвращает значение TIMESTAMP WITH TIME ZONE, которое сравнивается со значением TIMESTAMP.

На самом деле Oracle делает это:

SYSTIMESTAMP > FROM_TZ(LAST_UPDATE_TS + INTERVAL '5' MINUTE, SESSIONTIMEZONE)

Само сравнение выполняется для UT C раз.

SYSTIMESTAMP возвращается в часовом поясе операционной системы сервера базы данных. Если этот часовой пояс равен вашему текущему SESSIONTIMEZONE, то условие работает как ожидалось.

Либо измените часовой пояс сеанса на часовой пояс операционной системы сервера базы данных, либо попробуйте следующий:

LOCALTIMESTAMP > LAST_UPDATE_TS + INTERVAL '5' MINUTE

, который вообще не использует часовые пояса.

1 голос
/ 11 марта 2020

Вы сравниваете SYSTIMESTAMP, который имеет тип данных TIMESTAMP WITH TIME ZONE, с типом данных TIMESTAMP(6); для этого требуется преобразование в часовой пояс.

Если вы используете:

SELECT SESSIONTIMEZONE FROM DUAL;

Вы можете увидеть часовой пояс, который использует ваш сеанс.

On db <> fiddle, по умолчанию UT C (+00: 00) и работает:

SELECT DUMMY AS query1
FROM   DUAL
WHERE  TIMESTAMP '2020-03-11 06:06:00.070695 -05:00' > TIMESTAMP '2020-03-11 06:05:50.781167' + INTERVAL '5' MINUTE

Выходы:

| QUERY1 |
| :----- |
| X      |

Поскольку 2020-03-11 06:06:00.070695 -05:00 больше чем 2020-03-11 06:10:50.781167 +00:00.

Если вы измените часовой пояс сеанса:

ALTER SESSION SET TIME_ZONE = '-05:00';

и снова выполните тот же запрос (другой псевдоним столбца использовался для предотвращения кэширования):

SELECT DUMMY AS query2
FROM   DUAL
WHERE  TIMESTAMP '2020-03-11 06:06:00.070695 -05:00' > TIMESTAMP '2020-03-11 06:05:50.781167' + INTERVAL '5' MINUTE

Тогда выходные данные имеют нулевые строки:

| QUERY2 |
| :----- |

Если вы хотите вручную установить часовой пояс в преобразовании, тогда вы можете использовать функцию FROM_TZ:

SELECT DUMMY AS query3
FROM   DUAL
WHERE  TIMESTAMP '2020-03-11 06:06:00.070695 -05:00' > FROM_TZ( TIMESTAMP '2020-03-11 06:05:50.781167', '-05:00' ) + INTERVAL '5' MINUTE

, который, опять же, выводит нулевые строки:

| QUERY3 |
| :----- |

db <> fiddle здесь

0 голосов
/ 11 марта 2020

Делать это по-старому?

systimestamp -5 / (60 * 24)> LAST_UPDATE_TS

0 голосов
/ 11 марта 2020

После проверки нескольких форумов и других страниц stackoverflow, я попробовал это, и кажется, что теперь оно работает.

select *
from table
where cast(systimestamp as TIMESTAMP)  > (lst_updt_ts  + interval '3' minute);
...