Oracle датирует преобразование строки

У меня есть строковый столбец COL1, когда я делаю это

SELECT TO_CHAR(TO_DATE(COL1,'dd-mon-yy'), 'mm/dd/yyyy')
FROM TABLE1

Данные в COL1 находятся в dd-mon-yy, например: 27-11-89 и 89 - 1989, но выбор возвращает его как 11/27/2089.

Мне нужно сделать внутренний TO_DATE, потому что, если я этого не сделаю, я получаю неверную ошибку номера (ORA-01722: недопустимый номер)

Как можно показать 1989 вместо 2089? Пожалуйста, помогите

Ответ 1

Данные в COL1 находятся в dd-mon-yy

Нет, нет. Столбец DATE имеет не какой-либо формат. Он преобразуется (неявно) в это представление вашим SQL-клиентом при его отображении.

Если COL1 действительно является столбцом DATE, использующим to_date(), он бесполезен, потому что to_date() преобразует строку в DATE.

Вам нужно только to_char(), ничего больше:

SELECT TO_CHAR(col1, 'mm/dd/yyyy') 
FROM TABLE1

Что происходит в вашем случае: вызов to_date() преобразует DATE в значение символа (применяя формат по умолчанию NLS), а затем преобразует его обратно в DATE. Из-за этого двойного неявного преобразования некоторая информация теряется в пути.


Edit

Итак, вы сделали эту большую ошибку, чтобы сохранить DATE в столбце символов. И вот почему вы получаете проблемы сейчас.

Лучшее (и, если честно, только разумное) решение состоит в том, чтобы преобразовать этот столбец в DATE. Затем вы можете преобразовать значения в любое требуемое перепредставление, не беспокоясь о неявном преобразовании типа данных.

Но, скорее всего, ответ: "Я унаследовал эту модель, я должен с ней справиться" (она всегда, по-видимому, никто никогда не отвечает за выбор неправильного типа данных), тогда вам нужно использовать RR вместо YY:

SELECT TO_CHAR(TO_DATE(COL1,'dd-mm-rr'), 'mm/dd/yyyy')
FROM TABLE1

должен сделать трюк. Обратите внимание, что я также изменил mon на mm, так как ваш пример 27-11-89, у которого есть число за месяц, а не "слово" (например, NOV)

Подробнее см. руководство: http://docs.oracle.com/cd/B28359_01/server.111/b28286/sql_elements004.htm#SQLRF00215

Ответ 2

Попробуйте это. Oracle имеет эту особенность, чтобы отличать тысячелетия.

Как вы упомянули, если ваш столбец является varchar, то ниже запрос даст вам 1989 год.

выберите to_date (column_name, 'dd/mm/rr') из таблицы1;

Когда формат rr используется в год, оракул должен выполнить следующее:

если rr- > 00 to 49 --- > результат будет 2000 - 2049, если rr- > 50 to 99 --- > результат будет 1950 - 1999

Ответ 3

Если ваш столбец имеет тип DATE (как вы говорите), вам не нужно сначала преобразовывать его в строку (на самом деле вы сначала должны преобразовать его в строку, а затем явно в дату и снова явно к строке):

SELECT TO_CHAR(COL1, 'mm/dd/yyyy') FROM TABLE1

Формат даты, отображаемый для вашего столбца, является артефактом используемого вами инструмента (TOAD, SQL Developer и т.д.) и его языковых настроек.

Ответ 4

Еще одно замечание: вы пытаетесь преобразовать дату в mm/dd/yyyy, но если у вас есть какие-либо планы по сопоставлению этой конвертированной даты с какой-либо другой датой, убедитесь, что вы конвертируете ее только в формате yyyy-mm-dd поскольку to_char буквально преобразует его в строку, и с любым другим форматом мы получим нежелательный результат. Для получения более подробных объяснений следуйте этому: Сравнение дат в Oracle SQL