Кажется, что ручной запрос и запрос Talend выполняются в сеансах с разными часовыми поясами.
Вы не указываете часовой пояс в фиксированном значении, несмотря на наличие TZH:TZM
в модели формата;и на самом деле вы не можете использовать to_timestamp()
:
select to_timestamp('2018-08-25 00:00:00.0000000 +02:00','YYYY-MM-DD HH24:mi:ss:ff6 TZH:TZM')
from dual;
ORA-01821: date format not recognized
, потому что эта функция дает вам простую временную метку:
alter session set NLS_TIMESTAMP_FORMAT ='YYYY-MM-DD HH24:mi:ss.ff6';
alter session set NLS_TIMESTAMP_TZ_FORMAT ='YYYY-MM-DD HH24:mi:ss.ff6 TZH:TZM';
select to_timestamp('2018-08-25 00:00:00.0000000','YYYY-MM-DD HH24:mi:ss:ff6 TZH:TZM')
as plain_timestamp
from dual;
PLAIN_TIMESTAMP
--------------------------
2018-08-25 00:00:00.000000
Когда вы используете эту простую временную метку по сравнению с вашейВ столбце таблицы, который представляет собой временную метку с часовым поясом, происходит неявное преобразование в часовой пояс сеанса.Вы можете увидеть эффект от его установки вручную:
alter session set time_zone = 'Europe/London';
select cast(
to_timestamp('2018-08-25 00:00:00.0000000','YYYY-MM-DD HH24:mi:ss:ff6 TZH:TZM')
as timestamp with time zone
) as timestamp_with_session_zone
from dual;
TIMESTAMP_WITH_SESSION_ZONE
---------------------------------
2018-08-25 00:00:00.000000 +01:00
alter session set time_zone = 'America/New_York';
select cast(
to_timestamp('2018-08-25 00:00:00.0000000','YYYY-MM-DD HH24:mi:ss:ff6 TZH:TZM')
as timestamp with time zone
) as timestamp_with_session_zone
from dual;
TIMESTAMP_WITH_SESSION_ZONE
---------------------------------
2018-08-25 00:00:00.000000 -04:00
Таким образом, чтобы получить разные данные из двух ваших сеансов, это сравнение использует другое значение, поэтому часовые пояса сеанса должны быть разными.
Простое решение заключается в том, чтобы явно указать часовой пояс в фиксированном значении, но вам нужна другая функция, чтобы избежать ошибки, замеченной ранее;и желательно с регионом вместо смещения, чтобы учесть летнее время (при условии, что значения в вашей таблице также основаны на регионе):
select to_timestamp_tz('2018-08-25 00:00:00.0000000 Europe/Berlin','YYYY-MM-DD HH24:mi:ss:ff6 TZR')
as timestamp_with_berlin_zone
from dual;
TIMESTAMP_WITH_BERLIN_ZONE
---------------------------------
2018-08-25 00:00:00.000000 +02:00
или вы можете использовать литерал метки времени:
select timestamp '2018-08-25 00:00:00.0 Europe/Berlin' as timestamp_with_berlin_zone
from dual;
, который получает то же значение.
Я пытался отформатировать часовой пояс в запросе с помощью to_timestamp_tz (substr ('2018-08-25 00: 00: 00.0000000'), 1,25), «ГГГГ-ММ-ДД HH24: mi: ss.ff6 TZH: TZM» в часовом поясе «берлин / европа») в качестве input_timestamp, но все равно дает мне больше данных, чем ожидалось.
Игнорирование нечетного substr()
, который просто удаляет последние два нуля из того, что уже является фиксированной строкой, если вы сделаете:
select to_timestamp_tz('2018-08-25 00:00:00.0000000', 'YYYY-MM-DD HH24:mi:ss.ff6 TZH:TZM')
at time zone 'Europe/Berlin' as timestamp_with_wrong_time
from dual;
вы получите (мой сеанс все еще в Нью-Йорке побольший эффект)
TIMESTAMP_WITH_WRONG_TIME
---------------------------------
2018-08-25 06:00:00.000000 +02:00
Часовой пояс теперь тот, который вы ожидали, но time неверно.У вас та же проблема, что и раньше.Вы по-прежнему конвертируете фиксированное значение без указания часового пояса в метку времени с часовым поясом, поэтому он неявно использует часовой пояс сеанса:
select to_timestamp_tz('2018-08-25 00:00:00.0000000', 'YYYY-MM-DD HH24:mi:ss.ff6 TZH:TZM')
as timestamp_with_wrong_time
from dual;
TIMESTAMP_WITH_WRONG_TIME
---------------------------------
2018-08-25 00:00:00.000000 -04:00
, а затем at timezone 'Europe/Berlin'
просто дает ту же самую точкупо всемирному времени - полночь в Нью-Йорке, который является 04:00 UTC, но по берлинскому местному времени, которое является 06:00.Это тот же момент времени, только если смотреть из разных мест / часовых поясов.
Опять же, вам просто нужно указать часовой пояс для фиксированного времени, которое вы используете для сравнения - как timestamp '2018-08-25 00:00:00.0 Europe/Berlin'
.