Oracle - получить дату, имеющую значения метки времени

У нас есть ситуация, когда у нас есть таблица (скажем, Forms) в Oracle DB, в которой есть столбец (скажем, edition_date) типа date. Это было строго предназначено для хранения информации о дате в формате ГГГГ-ММ-ДД (например: 2012-11-23) без значения метки времени.

К сожалению, из-за проблемы с кодом многие строки были созданы со значениями метки времени. В этой таблице множество записей, и я хочу обновить только те строки, в которых были эти неверные данные. Я могу сделать это с помощью запроса

UPDATE forms SET edition_date = TRUNC( edition_date ) 

Я хочу добавить к нему предложение where, чтобы оно обновляло только неверные данные. Проблема в том, что я не уверен, как получить те строки, к которым добавлена ​​временная метка. Ниже приведен снимок данных, которые у меня есть:

    FORM_ID    EDITION_DATE
    5          2012-11-23
    6          2012-11-23 11:00:15
    ..
    11         2010-07-11 15:23:22
    ..
    13         2011-12-31 

Я хочу получить только строку с идентификаторами формы 6 и 11. Я пробовал использовать функции длины, но я думаю, что это хорошо только для строк. Есть какой-либо способ сделать это. Спасибо всем, кто может мне помочь.


person Chris    schedule 17.04.2013    source источник


Ответы (1)


Дата не имеет формата; вы только видите, как это отображается. Однако ответ на ваш вопрос, по сути, заключается в том, что вы сказали:

Я хочу добавить к нему предложение where, чтобы оно обновляло только неверные данные.

Итак, где дата не равна дате без времени:

update forms
   set edition_date = trunc(edition_date)
 where edition_date <> trunc(edition_date)

Чтобы этого больше не повторилось, вы можете добавить проверочное ограничение к вашему столу:

alter table forms 
  add constraint chk_forms_edition_date
      check ( edition_date = trunc(edition_date) );

Я бы посоветовал не использовать все вышеперечисленное. Не уничтожайте потенциально полезные данные. Вы должны просто выбрать trunc(edition_date), где вам не нужно время. Возможно, вы захотите использовать это время в будущем.

Вы правы, не используйте LENGTH() и т. д. для дат, это зависит от вашего NLS_DATE_FORMAT и поэтому могут различаться в зависимости от сеанса. Всегда используйте функции даты при работе с датами.

person Ben    schedule 17.04.2013
comment
+1 за методы, но я думаю, что советовать против их реализации может быть опрометчиво, не зная больше об источнике метки времени. Он может вообще не относиться к дате, а быть, например, артефактом времени создания записи. Небольшое примечание по проверочному ограничению - я бы определенно сделал это, но помните о проблеме с оптимизатором в какой-то версии (я думаю, 10.2), из-за которой ограничение также применялось в качестве предиката, который искусственно уменьшал предполагаемую кардинальность. - person David Aldridge; 17.04.2013
comment
Спасибо, Бен. Я думаю, что ваше предложение потрясающее и позаботится о моих опасениях по поводу любых нежелательных обновлений. Я согласен с вами в том, что вы не удаляете метку времени, поскольку на самом деле она предоставляет дополнительные данные. Я все еще разговариваю с нашим клиентом по этому поводу и надеюсь, что они согласятся на это предложение. - person Chris; 17.04.2013