У меня есть таблица oracle, которая содержит дату в формате дд-мм-гггг и дд / мм / гггг в том же поле. Теперь мне нужно преобразовать в один общий формат

#sql #oracle #datetime

#sql #Oracle #дата-время

Вопрос:

У меня есть таблица oracle, которая содержит дату в формате дд-мм-гггг и дд / мм / гггг в том же поле. Теперь мне нужно преобразовать в один общий формат. Пожалуйста, предложите, как подойти к этому?

Я пытался, но он терпит неудачу, поскольку он терпит неудачу из-за недопустимого месяца. Есть ли способ, которым я могу сначала определить, в каком формате указана дата, а затем на основе заявления case, которое я мог бы преобразовать. или что-то простое? Пожалуйста

Комментарии:

1. Вы уверены, что у вас нет значений в mm-dd-yyyy формате? Вы не получите ошибку из-за разных символов-разделителей (если вы не принудите точное совпадение, используя модель FX формата при преобразовании), поэтому ошибка, скорее всего, где-то в другом месте, и попытка указать месяц 13 даст вам ORA-01843: not a valid month . Если у вас есть даты в обоих DD-MM-YYYY MM-DD-YYYY форматах и, тогда у вас БОЛЬШИЕ проблемы, поскольку вы не можете знать, 01-02-2020 1 февраля или 2 января.

Ответ №1:

Я надеюсь, вы усвоили свой урок, и теперь вы собираетесь сохранить эти даты в типе данных date.

Ваши два разных формата даты на самом деле не важны, Oracle уже немного перестарался, когда дело доходит до разделения символов. например

 to_date('01/01/1900','dd-mm-yyyy') 
  

Не выдает ошибок

Я пытался, но он терпит неудачу, поскольку он терпит неудачу из-за недопустимого месяца.

Ваша ошибка возникает, потому что вы допустили значение, которое не соответствует ни одному из этих форматов в вашем столбце string.

Если у вас как минимум версия 12.2 (которая должна быть в 2020 году), вы можете использовать validate_conversion функцию для идентификации строк, которые не преобразуются в дату в вашем формате (https://docs.oracle.com/en/database/oracle/oracle-database/12.2/sqlrf/VALIDATE_CONVERSION.html#GUID-DC485EEB-CB6D-42EF-97AA-4487884CB2CD)

 select string_column
from  my_table
where  validate_conversion(string_column AS DATE,'dd/mm/yyyy') = 0
  

Другим дополнительным помощником, который мы получили в 12.2, было on conversion error предложение to_date . Так что вы можете сделать.

 alter table my_table add my_date date;
update my_table set my_date = to_date(my_string default null on conversion error,'dd/mm/yyyy');
  

Комментарии:

1. Да, я усвоил урок, чтобы не иметь поля varchar для хранения данных даты и времени, но существующую проблему необходимо решить. Спасибо за ценные коды, буду работать над этим. Мне также понравилась идея, предложенная @GMB, заменить ‘/’ на ‘-‘ . Спасибо Эндрю Сэйеру

2. Как я указал в своем ответе, путаница / и — на самом деле не является проблемой для Oracle. Обе версии могут быть успешно преобразованы в дату с любым разделителем. Ваша проблема в том, что данные — это что-то другое — вероятно, когда дни и месяцы переворачиваются, поскольку он жалуется, что не может преобразовать их в месяц. Если это так, то на самом деле, вероятно, некоторые данные были сохранены неправильно, но все еще технически действительны (01/02/2020 может быть февраль или январь), это будет невозможно очистить без дополнительной информации о строке.

Ответ №2:

Если вы уверены, что не существует другого формата, кроме этих двух, простой подход replace() :

 update mytable set mystring = replace(mystring, '/', '-');
  

Это преобразует все даты в формат dd-mm-yyyy .

Я бы предложил сделать шаг вперед и преобразовать эти строки в date столбец.

 alter table mytable add mydate date;
update mytable set mydate = to_date(replace(mystring, '/', '-'), 'dd-mm-yyyy');
  

Это приведет к сбою, если будут выполнены недопустимые строки даты. Я склонен считать это хорошей вещью, поскольку это ясно сигнализирует о том, что это проблема с данными. Если вы хотите избежать этого, вы можете использовать on conversion error , доступный начиная с Oracle 12:

 to_date(
    replace(mystring, '/', '-') default null on conversion error,
    'dd-mm-yyyy' 
)
  

Затем вы можете удалить столбец string, который больше не нужен.

Комментарии:

1. Спасибо @GMB, за эту потрясающую идею … это выглядит выполнимым, поскольку столбец, который у меня есть, имеет varchar, поэтому я могу легко использовать функцию replace. И позже может быть преобразована в поле дата-время. Попробую этот подход, надеюсь, это сработает.