Oracle
 sql >> база данни >  >> RDS >> Oracle

Времево клеймо на Oracle с прозрачен превод на стойностите на местната часова зона

TIMESTAMP WITH LOCAL TIME ZONE работи по следния начин:Когато трябва да работите с часови зони във вашето приложение, обичайният подход е

Точно така TIMESTAMP WITH LOCAL TIME ZONE работи - единствената разлика е

Поради тази причина не можете да промените DBTIMEZONEALTER DATABASE SET TIME_ZONE='...'; ) във вашата база данни, ако базата данни съдържа таблица с TIMESTAMP WITH LOCAL TIME ZONE колона и колоната съдържа данни.

SYSTIMESTAMP се връща в часовата зона на операционната система на сървъра на базата данни. DBTIMEZONE ене часовата зона на SYSTIMESTAMP или SYSDATE .

DBTIMEZONE дефинира вътрешния формат за съхранение на TIMESTAMP WITH LOCAL TIME ZONE колони за тип данни. Забравете това, не мога да си представя случай на употреба, при който ще имате нужда от него.

Всъщност вашата таблица е еквивалентна на този select:

select 
   CAST(systimestamp AS timestamp(0) with local time zone) as SYSTIMESTAMP_COL,
   CAST(sysdate AS timestamp(0) with local time zone) as SYSDATE_COL,
   CAST(current_timestamp AS timestamp(0) with local time zone) as CURRENT_TIMESTAMP_COL,
   CAST(timestamp '2017-03-15 19:02:00' AS timestamp(0) with local time zone) as DATE_COL
from dual;

Когато направите CAST({time without time zone} with local time zone) след това се опитвате да конвертирате стойност за дата/час без информация за часовата зона в стойност за дата/час с часова зона. По принцип това не е възможно, тъй като Oracle няма информация за часовата зона, така че Oracle приема часова зона. Ако направите такова прехвърляне, тогава Oracle винаги разглежда {време без часова зона} като дадено в SESSIONTIMEZONE (в момента на преобразуване).

Така че CAST(sysdate AS timestamp(0) with local time zone) е еквивалентен на

CAST(FROM_TZ(TO_TIMESTAMP(SYSDATE), SESSIONTIMEZONE) AS TIMESTAMP(0) WITH LOCAL TIME ZONE)` 

респ. CAST(timestamp '2017-03-15 19:02:00' AS timestamp(0) with local time zone) означава

CAST(FROM_TZ(TIMESTAMP '2017-03-15 19:02:00', SESSIONTIMEZONE) AS TIMESTAMP(0) WITH LOCAL TIME ZONE)

За SYSDATE това всъщност е грешно, защото SYSDATE се дава в часовата зона на операционната система на сървъра на базата данни, а не в SESSIONTIMEZONE. За второто зависи от вашето намерение дали резултатът е правилен или не.

SYSTIMESTAMP връща стойност TIMESTAMP WITH TIME ZONE , той винаги е независим от текущия ви SESSIONTIMEZONE . Но ако преобразувате в TIMESTAMP WITH LOCAL TIME ZONE той се преобразува в текущата ви местна часова зона, разбира се. Можете също да използвате CURRENT_TIMESTAMP или SYSTIMESTAMP AT LOCAL което прави повече или по-малко същото.

Този код

изглежда грешно. Резултатът трябва да бъде

-- SYSTIMESTAMP_COL                   15/03/2017 16:01:14
-- SYSDATE_COL                        15/03/2017 19:01:14
-- CURRENT_TIMESTAMP_COL              15/03/2017 16:01:14
-- DATE_COL                           15/03/2017 19:02:00

Разликите изглеждат така, както трябва да бъдат, но абсолютните стойности изглеждат "фалшиви" (или има реален проблем с вашата база данни).



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Клониране на ORACLE_HOME

  2. Oracle как да разделя данните и да получава записи на всеки 10%

  3. Изберете колони от индекса на таблицата

  4. PK е нарушен в oracle sql

  5. Доставчици на Oracle от трети страни за .Net с поддръжка на тип обект