ORA-01861 исключение, которое то есть, то нет
create table test_date (f1 date);
insert into test_date values(null);
commit;
-- statement 1
update test_date set f1 = TO_DATE( '06.02.2023', 'YYYY-MM-DD HH24:MI:SS' );
-- statement 2
update test_date set f1 = TO_DATE( '06.02.2024', 'YYYY-MM-DD HH24:MI:SS' );
commit;
Первый запрос обработается без исключения.
Второй запрос выбросит ошибку ORA-01861.
В таблице в поле f1 будет лежать вообще что-то загадочное.
В чем проблема?
Ответы (1 шт):
Чтобы ответить на этот вопрос, в чем разница между 2023 и 2024, можно написать простой скрипт.
create table test_dataformet_log (
inp_date date
,str_date varchar2(64)
,new_date date
,matbe_exception number(1)
,errcode varchar2(64)
);
declare
v_stdate date := to_date('01-01-1900', 'DD-MM-YYYY');
v_newdate date;
v_cnt number := 50000;
v_strdate varchar2(64);
v_errcd varchar2(32);
begin
for pos in 1..v_cnt loop
v_stdate := v_stdate + 1;
declare
begin
v_strdate := to_char(v_stdate, 'DD.MM.YYYY');
v_newdate := to_date(v_strdate, 'YYYY-MM-DD HH24:MI:SS');
insert into test_dataformet_log values (v_stdate, v_strdate, v_newdate, null, null);
exception
when others then
v_errcd := SQLCODE;
insert into test_dataformet_log values (v_stdate, v_strdate, null, 1, v_errcd);
end;
end loop;
end;
/
И самый беглый взгляд на результаты скажет, что оракл не проверяет соответствие строки ожидаемому формату даты, а неведомой перестановкой байт просто пытается сконвертировать то, что подали на вход.
Так первые две цифры года становятся числом, месяц остается на месте, число становится годом (7 число месяца = 7 год нашей эры), а вот последние две цифры года попадают в разряд часов.
Исключение генерируются только если часы оказываются больше 23.
То есть, если вы пытаетесь конвертировать таким способом даты с 01.01.2000 по 31.12.2023 - никаких исключений, все сконвертируется.