Oracle: как избежать значения NULL в to_date

У меня есть функциональный оператор выбора, в котором есть предложение where, в предложении where есть такой оператор ...

to_date (camp.start_date, 'MM / DD / YYYY')> = to_date (: from_date, 'YYYY-MM-DD HH24: MI: SS')

Однако, если camp.start_date имеет значение NULL или не имеет строк, он генерирует исключение -

ORA-01858: был обнаружен нечисловой символ вместо ожидаемого числа.

camp.start_date на самом деле является VARCHAR2, который мне нужно преобразовать в дату (да, я знаю, что, вероятно, это должно быть поле даты, но у меня нет возможности изменить это).

Я пробовал что-то подобное ...

to_date(NVL(camp.start_date,SYSDATE), 'MM/DD/YYYY') >= 
to_date(:from_date, 'YYYY-MM-DD HH24:MI:SS')

Что все еще дает мне ошибку. Также пробовал

где camp.start_date не равно null, а to_date (camp.start_date, 'MM / DD / YYYY')> = to_date (: from_date, 'YYYY-MM-DD HH24: MI: SS')

та же проблема. Как лучше всего обойти это? Обычно to_date взрывается и выдает ошибку, когда camp.start_date не является допустимой датой.


person HelloWorld    schedule 11.03.2014    source источник
comment
Также по какой-то причине это нормально в db_visualizer, но выдает ошибку при использовании Rails?   -  person HelloWorld    schedule 12.03.2014


Ответы (4)


Если start_date равно NULL, исключение не генерируется.

select to_date( null, 'mm/dd/yyyy' ) 
  from dual

является совершенно правильным оператором SQL, возвращающим NULL.

Ошибка, которую вы получаете, явно подразумевает, что по крайней мере некоторые из строк в столбце start_date на самом деле не являются строками в ожидаемом вами формате или соответствуют недопустимым датам (т.е. строка '13/35/2007'). Вы можете написать функцию, которая проверяет, можно ли преобразовать строку в дату и возвращать либо преобразованную дату, либо NULL. Затем вы можете использовать это вместо to_date.

CREATE OR REPLACE FUNCTION my_to_date( p_str    IN VARCHAR2,
                                       p_format IN VARCHAR2 )
  RETURN DATE
IS
BEGIN
  RETURN to_date( p_str, p_format );
EXCEPTION
  WHEN OTHERS
  THEN
    RETURN NULL;
END;

а затем используйте my_to_date вместо to_date. Это должно устранить ошибку, которую вы получаете. Однако вы, вероятно, захотите очистить данные, чтобы избавиться от недопустимых строк.

person Justin Cave    schedule 11.03.2014
comment
Вот и все, некоторые даты похожи на 01.01.2013, может быть, они должны быть 01.01.2013? - person HelloWorld; 12.03.2014
comment
@HelloWorld - это будет успешно преобразовано, дело не в начальных нулях. Вы можете найти строки, где my_to_date( camp.start_date, 'MM/DD/YYYY') is null and camp.start_date is not null, чтобы узнать, что это за недопустимые строки. - person Justin Cave; 12.03.2014

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

to_date(NVL(start_date,to_char(SYSDATE,'MM/DD/YYYY')), 'MM/DD/YYYY') >= 
to_date(from_date, 'YYYY-MM-DD HH24:MI:SS')
person Clint    schedule 19.05.2015

Вы можете использовать это так:

NVL(TO_CHAR(SYSDATE,'DD-MM-YYYY'),' ')

Это преобразует дату в строковый формат, а затем в пустую строку.

person venkatesh    schedule 28.03.2019

Делает

NVL(TO_DATE(start_date,'MM/DD/YYYY'),SYSDATE) >= from_date

сделать больше смысла, если from_date имеет ненулевое значение типа даты? Если from_date может быть нулевым или не является значением даты, тогда сделать это?

NVL(TO_DATE(start_date,'MM/DD/YYYY'),SYSDATE) >= NVL(TO_DATE(from_date,'MM/DD/YYYY'),SYSDATE)

Что-то вроде сравнения яблок с яблоками?

person Vincent Quiles    schedule 17.01.2019
comment
Это не дает ответа на вопрос. Вы можете искать похожие вопросы или обратиться к связанным и связанным вопросам в правой части страницы, чтобы найти ответ. Если у вас есть связанный, но другой вопрос, задайте новый вопрос и включите ссылку на этот, чтобы помочь понять контекст. См .: Задавайте вопросы, получайте ответы, не отвлекаясь - person Zoe; 17.01.2019