У меня есть этот запрос в оракуле:
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.
кто нибудь знает в чем проблема?
Ответ 1 · рейтинг 2 · MT0
Я предполагаю, что вы сохранили свои даты в виде строки в формате 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';
Ответ 2 · рейтинг 1 · Kapitany
Если типом данных last_update является дата, не используйте функцию to_date:
DELETE FROM my_table
WHERE last_update < to_date('01/01/2000', 'DD/MM/YYYY');