Как сравнить строку даты из столбца varchar со строкой даты из ввода в Oracle Sql? - PullRequest
1 голос
/ 10 апреля 2020

У меня проблема с запросом, чтобы сравнить тип значения столбца varchar2 со строкой даты значения из входных данных. Но это всегда возвращает ошибку Day of month must be between 1 and last day of month.... Особенно, когда я добавляю предложение Order By за предложением Where. Я также проверяю, не равен ли столбец '0'.

Например: * Таблица

+----+----------------------+
+ ID +  DATE_IN (VARCHAR2)  +
+----+----------------------+
+  1 + 01/04/2020           +
+----+----------------------+
+  2 + 02/04/2020           +
+----+----------------------+
+  3 + 04/04/2020           +
+----+----------------------+
+  4 + 08/04/2020           +
+----+----------------------+
+  5 + 0                    +
+----+----------------------+
  • Строка INPUT: '10 / 04/2020 '

  • Мой запрос:

SELECT *
FROM `table_name`
WHERE DATE_IN IS NOT NULL
   AND DATE_IN <> '0'
   AND TO_DATE(DATE_IN,'DD/MM/YYYY') >= TO_DATE('10/04/2020','DD/MM/YYYY')
ORDER BY ID

Ответы [ 4 ]

1 голос
/ 10 апреля 2020

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

Однако, начиная Oracle 12 c выпуск 2, эта задача получает гораздо проще: вы можете использовать cast() с опцией on conversion error для этого.

Вот запрос, который вытащит все недопустимые строки даты из вашей таблицы:

select * 
from mytable
where 
    date_in is not null 
    and cast(datein as date default null on conversion error, 'dd/mm/yyyy') is null

Вы можете также используйте ту же технику непосредственно в вашем запросе:

select *
from mytable
where 
    cast(datein as date default null on conversion error, 'dd/mm/yyyy') 
        >= to_date('10/04/2020','dd/mm/yyyy')
order by id
0 голосов
/ 10 апреля 2020

Вы также можете избежать значений 0 или NULL с помощью такого подзапроса, как:

--this creates a dataset without 0 and null values
WITH t AS (
    SELECT *
    FROM table_name
    WHERE 
        date_in IS NOT NULL
        AND date_in <> '0'
)
-- this will select the values you require
SELECT *
FROM t
WHERE
    to_date(date_in, 'DD/MM/YYYY') >= TO_DATE('10/04/2020', 'DD/MM/YYYY')
ORDER BY id;
0 голосов
/ 10 апреля 2020

Если все ваши значения на самом деле являются действительными представлениями даты или равны нулю, проблема, вероятно, заключается в том, что Oracle оценивает вызов to_date(), прежде чем исключить нули. Вы можете избежать этого, переместив проверку нуля в регистр:

SELECT *
FROM table_name
WHERE TO_DATE(CASE WHEN DATE_IN <> '0' THEN DATE_IN END, 'DD/MM/YYYY')
  >= TO_DATE('10/04/2020','DD/MM/YYYY')
ORDER BY ID;

Хранение дат в виде строк, конечно, не очень хорошая идея ...

0 голосов
/ 10 апреля 2020

У вас неверные данные - поэтому вы не хотите хранить даты в виде строк.

В вашем случае вы можете искать их:

select date_in
from table_name
where substr(date_in, 4, 2) <= '00' or
      substr(date_in, 4, 2) > '12'

Я бы затем рекомендуем исправить данные и изменить тип данных на date.

...