Почему Oracle меняет функцию построения индекса вместо вывода ошибки? ORA-01722: invalid number по индексу на поле с типом varchar2

Есть пустая таблица mySomeTable с 2мя полями

create table mySomeTable (
    IDRQ VARCHAR2(32 CHAR),
    PROCID VARCHAR2(64 CHAR)
);

Создаю индекс на таблице по полю PROCID VARCHAR2(64 CHAR) используя следующую команду:

create index idx_PROCID on mySomeTable(trunc(PROCID));

Как можно увидеть, в скрипте построения индекса допущена ошибка и скрипт будет пытаться построить индекс по функции trunc().

trunct() - функция для работы с датами или числами

Данный скрипт построения индекса успешно отрабатывает и создает индекс, не выводя каких либо предупреждений и ошибок.

Создается индекс на таблице по функции TRUNC(TO_NUMBER(PROCID))

При последующей попытке вставить или изменить запись в таблице, если, PROCID нельзя преобразовать в число, получаю ошибку ORA-01722: invalid number, что собственно логично.

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

Вопрос: Почему Oracle меняет функцию построения индекса, вместо того, что бы выдать ошибку? И как этого можно избежать в будущем?

Версия Oracle 19.14

Пост с ошибкой ORA-01722: invalid number при вставке в поле VARCHAR2 был сделан когда мистика не разгадывалась, но после опубликования вопроса, случайно увидел построенный индекс, т.к. начал перебирать все возможные и не возможные варианты.

Вот что stackoverflow на русском делает - стоит задать вопрос и тут же находится решение.


Ответы (1 шт):

Автор решения: SwaD

Ошибка кроется в преобразовании типов! А Oracle их делает много.

Функция TRUNC принимает в качестве параметра тип NUMBER или DATE.

Нам никто не запрещал хранить числа или даты в полях формата VARCHAR2.

В документации oracle сказано:

  • Если неявное преобразование типа данных происходит в выражении индекса, то база данных Oracle может не использовать индекс, поскольку он определен для типа данных, предшествующего преобразованию. Это может негативно сказаться на производительности.

Oracle рекомендует указывать явные преобразования, а не полагаться на неявные или автоматические преобразования.

Предположительно, именно поэтому Oracle на самом деле выбирает применение явного преобразования при создании индекса.

В любом случае, при выполнении запроса, получили бы ту же ошибку, если бы выражение индекса не было изменено. Неявное преобразование строки в число выдало бы ошибку ORA-01722: invalid number

→ Ссылка