значение года в таблице в оракуле

У меня есть этот запрос в оракуле:

 DELETE FROM my_table
 WHERE to_date(last_update, 'DD/MM/YYYY') < to_date('01/01/2000', 'DD/MM/YYYY');

когда я запускаю это, я получаю эту ошибку: ORA-01841: (полный) год должен быть между -4713 и +9999 и не должен быть 0

в таблице нет ни одного значения 0.

кто нибудь знает в чем проблема?


person mona shiri    schedule 31.03.2021    source источник
comment
Каков тип данных вашего столбца last_update?   -  person Kapitany    schedule 31.03.2021
comment
@Kapitany это: ДАТА ПО УМОЛЧАНИЮ to_date('1900 01 01', 'гггг мм дд') NOT NULL   -  person mona shiri    schedule 31.03.2021
comment
Не используйте TO_DATE для значений, которые уже имеют тип данных DATE.   -  person MT0    schedule 31.03.2021


Ответы (2)


Я предполагаю, что вы сохранили свои даты в виде строки в формате DD/MM/YYYY; было бы лучше, если бы вы сохранили их все как тип данных DATE, и тогда вам не пришлось бы выполнять это преобразование (и вы бы использовали наиболее подходящий тип данных для данных).

Из Oracle 12 вы можете использовать:

SELECT *
FROM   my_table
WHERE  TO_DATE( last_update, 'DD/MM/YYYY' DEFAULT NULL ON CONVERSION ERROR ) IS NULL;

Чтобы определить строки, вызывающие это исключение.


Если вы уже храните их как тип данных DATE, не используйте TO_DATE для значения, которое уже является DATE, поскольку TO_DATE ожидает строку, поэтому Oracle неявно преобразует ваш DATE в строку, а затем попытается преобразовать ее обратно и ваш запрос эффективно:

DELETE FROM my_table
WHERE  TO_DATE(
         TO_CHAR(
           last_update,
           ( SELECT value FROM NLS_SESSION_SETTINGS WHERE PARAMETER = 'NLS_DATE_FORMAT' )
         ),
         'DD/MM/YYYY'
       ) < to_date('01/01/2000', 'DD/MM/YYYY');

И если NLS_DATE_FORMAT и ваша модель формата не совпадают, вы получите ошибки (или, что еще хуже, запрос будет успешным, и ваши данные будут несогласованными, поскольку они могут поменять местами дни и месяцы или месяцы и годы).

Вместо этого просто используйте:

DELETE FROM my_table
WHERE last_update < DATE '2000-01-01';
person MT0    schedule 31.03.2021

Если типом данных last_update является дата, не используйте функцию to_date:

DELETE FROM my_table
 WHERE last_update < to_date('01/01/2000', 'DD/MM/YYYY');
person Kapitany    schedule 31.03.2021