Непосредственная проблема заключается в том, что вы вызываете to_date()
для фиксированного значения. Часть then
возвращает исходное строковое значение даты из файла; else
возвращает date
; что приводит к сообщению «ожидаемая дата получения char».
Если вы удалите часть to_date()
, все значения будут загружены как 1900-01-01, потому что у вас неверный оператор case. Вы сравниваете значение :COLUMN_DOB
со строкой 'isdate(:COLUMN_DOB)=1'
. Это не вызов функции, это фиксированная строка, и ваше поле даты никогда не будет точно соответствовать этому тексту. Таким образом, case
всегда переходит в else
и получает фиксированное значение. Вы также, кажется, смешиваете две формы оператора case
.
Так должно быть:
... "CASE WHEN isdate(:COLUMN_DOB)=1 THEN :COLUMN_DOB ELSE '19000101' END"
Что, если предположить, что вы создали функцию isdate()
— поскольку это не встроенная функция Oracle — с маской формата по умолчанию, что-то вроде этого на основе версии AskTom:
create or replace function isdate (p_string in varchar2,
p_fmt in varchar2 := 'YYYYMMDD')
return number as
l_date date;
begin
if l_date is null then
return 0;
end if;
l_date := to_date(p_string, p_fmt);
return 1;
exception
when others then
return 0;
end;
/
... поставит действительные даты, как указано, и недействительные даты как 1900-01-01. Нулевая проверка также означает, что нули будут вставлены как 1900-01-01; возможно, проще иметь его здесь, чем пытаться обрабатывать его отдельно в управляющем файле.
Возможно, вы могли бы еще больше упростить его, создав функцию, которая пытается преобразовать строку и вернуть дату, и просто вызывая ее в управляющем файле без маски date
или оператора case
. Этот подход также описан в этой ссылке AskTom.
Лично я, вероятно, предпочел бы, чтобы столбец оставался нулевым, а не присваивал ему магическое число. Нет ничего невозможного в том, чтобы иметь кого-то с действительной датой рождения 01.01.1900.
Если вы все равно создаете новую функцию, вы можете сделать это вместо этого:
create or replace function my2date(p_str in varchar2) return date is
begin
return to_date(nvl(p_str, '19000101'), 'YYYYMMDD');
exception
when others then -- just about acceptable here
return date '1900-01-01';
end;
/
который вы можете выполнить из SQL * Plus, SQL Developer, Toad или любого другого клиента, который вы используете. И тогда ваш управляющий файл будет иметь:
COLUMN_DOB "my2date(:COLUMN_DOB)"
Я не думаю, что есть способ сделать это без использования функции. Если вместо этого вы использовали внешнюю таблицу, то вы могли бы использовать анонимный блок для преобразования, я полагаю, но если вы застряли с SQL * Loader, то я считаю, что функция - это единственный способ остановить неверную дату, из-за которой вся строка быть отвергнутым.
person
Alex Poole
schedule
15.08.2013