Oracle: установить часовой пояс для столбца - PullRequest
1 голос
/ 23 марта 2010

Мне нужно выполнить миграцию даты-> отметки времени с часовым поясом, аналогичным описанному здесь: Перенос столбцов Oracle DATE в TIMESTAMP с часовым поясом .Но мне нужно сделать дополнительное преобразование (необходимо для правильной работы с устаревшими приложениями): для всех дат нам нужно изменить часовой пояс на UTC и установить время на 12:00 вечера.Так что теперь даты хранятся в локальной базе данных (Нью-Йорк) часового пояса.Мне нужно преобразовать их таким образом

25/12/2009 09:12 AM (местный часовой пояс) в столбце даты => 25.12.2009 12:00 PM UTC с меткой местного часового пояса.

Не могли бы вы посоветовать, как установить часовой пояс для значения даты в Oracle (я нашел только предложения о том, как конвертировать из одного часового пояса в другой) (например, в Java есть метод setTimeZone для объектов Calendar).

Мы хотим сделать преобразование следующим образом:

  1. переименовать старый столбец даты в NAME_BAK
  2. создать новую метку времени столбца с локальным часовым поясом
  3. выполнить итерацию по старому столбцудля ненулевых значений установите часовой пояс UTC, время 12:00 PM
  4. удалить старый столбец после тестирования этой миграции

Ответы [ 2 ]

0 голосов
/ 23 марта 2010

Создание и заполнение нового столбца ...

SQL> alter table t23
  2      add new_col timestamp(3) with time zone
  3  /

Table altered.

SQL> update t23
  2      set new_col = col3
  3  /

7 rows updated.

SQL> select to_char(new_col,'DD-MON-YYYY HH24:MI:SS.FF3 TZR') new_col
  2  from t23
  3  /

NEW_COL
----------------------------
22-MAR-2010 03:20:58.000 PST
21-MAR-2010 03:20:58.000 PST
20-MAR-2010 03:20:58.000 PST
19-MAR-2010 03:20:58.000 PST
18-MAR-2010 03:20:58.000 PST
17-MAR-2010 03:20:58.000 PST
16-MAR-2010 03:20:58.000 PST

7 rows selected.

SQL> 

Итак, теперь, чтобы установить значения COL3 в полдень по Гринвичу или по Гринвичу, как мы, британцы (и Oracle) знаем это:*

Давайте посмотрим на результат:

SQL> alter session set time_zone = 'PST'
  2  /

Session altered.

SQL> select to_char(new_col,'DD-MON-YYYY HH24:MI:SS.FF3 TZR') as orig_val
  2         , to_char(col3,'DD-MON-YYYY HH24:MI:SS.FF3 TZR') as upd_val
  3  from t23
  4  /

ORIG_VAL                     UPD_VAL
---------------------------- ----------------------------
22-MAR-2010 03:20:58.000 PST 22-MAR-2010 12:00:00.000 GMT
21-MAR-2010 03:20:58.000 PST 21-MAR-2010 12:00:00.000 GMT
20-MAR-2010 03:20:58.000 PST 20-MAR-2010 12:00:00.000 GMT
19-MAR-2010 03:20:58.000 PST 19-MAR-2010 12:00:00.000 GMT
18-MAR-2010 03:20:58.000 PST 18-MAR-2010 12:00:00.000 GMT
17-MAR-2010 03:20:58.000 PST 17-MAR-2010 12:00:00.000 GMT
16-MAR-2010 03:20:58.000 PST 16-MAR-2010 12:00:00.000 GMT

7 rows selected.

SQL>

Осталось только удалить столбец резервной копии ...

SQL> alter table t23 drop column new_col
  2  /

Table altered.

SQL>

Хотя, если это большая таблица, выможет предпочесть установить его на UNUSED, а затем отбросить в медленное время.

0 голосов
/ 23 марта 2010

Возможно, вы захотите прочитать документацию о типах данных Oracle:

  • a DATE не имеет часового пояса, эта информация просто не сохраняется с этим типом данных.Столбец
  • a TIMESTAMP WITH LOCAL TIME ZONE имеет такое же смещение часового пояса, что и база данных.Вы не можете указать другое смещение для столбца этого типа.

Он отличается от TIMESTAMP WITH TIME ZONE тем, что данные, хранящиеся в базе данных, нормализованы к времени базы данныхзона , а смещение часового пояса не сохраняется как часть данных столбца.Когда пользователь получает данные, Oracle возвращает их в часовом поясе локального сеанса пользователя.Смещение часового пояса - это разница (в часах и минутах) между местным временем и UTC (Всемирное координированное время - ранее среднее время по Гринвичу).Этот тип данных полезен для отображения информации о дате в часовом поясе клиентской системы в двухуровневом приложении.

Если вы хотите сохранить часовой пояс, вам нужно будет использовать тип данных TIMESTAMP с временной зоной .

Вы бы преобразовали дату в метку времени с помощью функции to_timestamp_tz , например:

SQL> WITH DATA AS (
  2     SELECT to_date('25/12/2009 09:12 AM', 'DD/MM/YYYY HH:MI AM') dd FROM dual
  3  )
  4  SELECT dd,
  5         to_timestamp_tz(to_char(dd, 'YYYYMMDD')||' GMT', 'YYYYMMDD TZR') tz
  6    FROM DATA;

DD          TZ
----------- -------------------------------------------------
25/12/2009  25/12/09 00:00:00,000000000 GMT
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...