To_char и To_date - PullRequest
       42

To_char и To_date

0 голосов
/ 08 октября 2018

Я борюсь с одним отчетом, содержащим столбец varchar2 в качестве даты в формате MON-YY

, что я хочу сделать, это преобразовать значение этого столбца в дату, чтобы я мог выполнить некоторый процесс на нем, например,как фильтрация с помощью> или <или даже между и установить две даты </p>

Имя моего столбца: BAL.PERIOD_NAME ниже является ошибкой обращения к условию ORA-01843: недопустимый месяц

AND TO_DATE(BAL.PERIOD_NAME,'MON-YY')  > TO_DATE('FEB-18','MON-YY')

спасибозаранее

Ответы [ 3 ]

0 голосов
/ 08 октября 2018

Убедитесь, что вы используете правильную маску формата для даты, которую вы конвертируете.

Работает:

select  TO_DATE('feb-18','MON-YY') from dual

Выдает ошибку «Недопустимый месяц»:

select  TO_DATE('02-18','MON-YY') from dual
0 голосов
/ 09 октября 2018

Хранение значений даты в виде строк, таких как 'FEB-18', на самом деле является недостатком дизайна.Вам следует подумать о переходе на тип данных DATE (или TIMESTAMP).

  • Вы никогда не слышали о Year-2000-Problem ?Ну, я полагаю, когда все в мире ИТ говорили о проблеме Y2K, многие нынешние разработчики программного обеспечения были еще детьми.
  • Строка может быть искажена любым способом.
  • Даже если строка имеет правильный формат, вы можете столкнуться с проблемой языковых настроек.

В любом случае, возможно, это только языковая проблема.Попробуйте это

WHERE TO_DATE(BAL.PERIOD_NAME,'MON-RR', 'NLS_DATE_LANGUAGE = American') > DATE '2018-02-01'

Если вы используете Oracle 12.2 или новее, вы можете использовать функцию VALIDATE_CONVERSION :

WHERE VALIDATE_CONVERSION(BAL.PERIOD_NAME, 'MON-RR', 'NLS_DATE_LANGUAGE = American') = 1

Если у вас нет Oracle 12.2а затем напишите свою собственную функцию, например, так:

CREATE OR REPLACE FUNCTION CONVERT_TO_DATE(str in VARCAHR2) RETURN DATE IS
BEGIN
   RETURN TO_DATE(str, 'MON-RR', 'NLS_DATE_LANGUAGE = American');
EXCEPTION
   WHEN OTHERS THEN
      RETURN NULL;  
END CONVERT_TO_DATE;
0 голосов
/ 08 октября 2018

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

WITH cte(month)
AS
(
SELECT 1 month
       FROM dual
UNION ALL
SELECT month + 1 month
       FROM cte
       WHERE month + 1 <= 12
)
SELECT *
       FROM bal
       WHERE substr(period_name, 1, 3) NOT IN (SELECT to_char(to_date(month, 'MM'), 'MON')
                                                      FROM cte);
...