Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Znacznik czasu Oracle z przezroczystym tłumaczeniem wartości lokalnej strefy czasowej

TIMESTAMP WITH LOCAL TIME ZONE działa tak:Kiedy musisz pracować ze strefami czasowymi w swojej aplikacji, powszechnym podejściem jest

Dokładnie tak TIMESTAMP WITH LOCAL TIME ZONE działa - jedyna różnica to

Z tego powodu nie możesz zmienić DBTIMEZONE (z ALTER DATABASE SET TIME_ZONE='...'; ) w Twojej bazie danych, jeśli baza danych zawiera tabelę z TIMESTAMP WITH LOCAL TIME ZONE kolumna i kolumna zawiera dane.

SYSTIMESTAMP jest zwracany w strefie czasowej systemu operacyjnego serwera bazy danych. DBTIMEZONE jest nie strefa czasowa SYSTIMESTAMP lub SYSDATE .

DBTIMEZONE definiuje wewnętrzny format przechowywania TIMESTAMP WITH LOCAL TIME ZONE kolumny typu danych. Zapomnij o tym, nie wyobrażam sobie żadnego przypadku użycia, w którym byłoby to potrzebne.

Właściwie Twoja tabela jest odpowiednikiem tego wyboru:

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;

Kiedy wykonujesz CAST({time without time zone} with local time zone) następnie próbujesz przekonwertować wartość daty/godziny bez informacji o strefie czasowej na wartość daty/godziny ze strefą czasową. W zasadzie nie jest to możliwe, ponieważ Oracle nie ma informacji o strefie czasowej, więc Oracle zakłada strefę czasową. Jeśli wykonasz takie rzutowanie, Oracle zawsze uważa {czas bez strefy czasowej} jak podano w SESSIONTIMEZONE (w momencie konwersji).

Więc CAST(sysdate AS timestamp(0) with local time zone) jest odpowiednikiem

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

ew. CAST(timestamp '2017-03-15 19:02:00' AS timestamp(0) with local time zone) oznacza

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

Dla SYSDATE jest to właściwie błędne, ponieważ SYSDATE jest podany w strefie czasowej systemu operacyjnego serwera bazy danych, a nie w SESSIONTIMEZONE. W przypadku drugiego zależy to od twojej intencji, czy wynik jest poprawny, czy nie.

SYSTIMESTAMP zwraca wartość TIMESTAMP WITH TIME ZONE , jest zawsze niezależny od aktualnego SESSIONTIMEZONE . Ale jeśli przekonwertujesz na TIMESTAMP WITH LOCAL TIME ZONE oczywiście zostanie przekonwertowany na aktualną lokalną strefę czasową. Możesz też użyć CURRENT_TIMESTAMP lub SYSTIMESTAMP AT LOCAL który robi mniej więcej to samo.

Ten kod

wydaje się być niesłuszne. Wynik powinien być

-- 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

Różnice wyglądają tak, jak powinny, ale wartości bezwzględne wydają się być „sfałszowane” (lub istnieje prawdziwy problem z bazą danych).



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PL/SQL niewystarczające uprawnienia w zapytaniu możliwe ręcznie

  2. Napotkany błąd SQL:ORA-01843:niepoprawny miesiąc

  3. Podczas otwierania połączenia Oracle obiekt połączenia jest pusty

  4. Maksymalna długość VARCHAR to 4000, ale można zapisać tylko 2666 bajtowy tekst w języku tajskim

  5. Jak mogę użyć FOR UPDATE z JOIN w Oracle?