Причина, по которой вы не можете перехватить исключение invalid_number, заключается в том, что вы объявляете входной параметр как число. Когда вы вызываете вашу функцию, Oracle пытается сначала преобразовать строку в число (и, конечно, не удается, , прежде чем вводить код вообще ).
Если вы измените входной параметр на varchar2, то преобразование в число (неявное в данном случае) будет выполнено внутри функции, и недопустимые числа могут быть перехвачены и обработаны, как вы хотите (здесь я просто возвращаю другую строку для обозначения вопроса):
create or replace function is_odd_even(i_num in varchar2)
return varchar2
is
begin
-- conversion to number is done here
if (mod(i_num, 2) = 0) then
return 'EVEN';
else
return 'ODD';
end if;
exception
when INVALID_NUMBER or VALUE_ERROR then
-- do something meaningful
return 'INV';
end;
Пример использования:
with x as (
select '1' as val from dual
union all
select 'SP' as val from dual
union all
select '2' as val from dual
)
select x.val, is_odd_even(x.val)
from x;
Выход:
1 ODD
SP INV
2 EVEN