Обычный способ решить эту проблему с помощью пользовательской функции:
create or replace function is_number (p_str in varchar2) return varchar2 is
n number;
rv varchar2(1);
begin
begin
n := to_number(p_str);
rv := 'Y';
exception
when others then
rv := 'N';
end;
return rv;
end;
/
select column_name, value, is_number(value) as is_number
from table1
where is_number(value) = 'N'
/
В Oracle 12c R2 мы приобрели встроенную функцию для этого: validate_conversion()
, которая обрабатывает множество типов данных. Узнать больше .
select column_name
, value
from table1
where validate_conversion(value as number) = 0
/
Вот демо на db <> fiddle .
Решения Regex сложно найти правильное решение. Легко сформулировать выражения, которые исключают действительные числа (такие как -80.98
) или включают не числа (такие как (12-34-56
). Даже мы правильно понимаем этот бит (как решение решения Гордона ), что происходит, если мы хотим разрешить десятичные разделители или символы валюты? Или научную запись? Это грязное регулярное выражение. UDF легко расширить для обработки маски форматирования, и validate_conversion()
делает это изначально:
SELECT VALIDATE_CONVERSION('$100,00' AS NUMBER,
'$999D99', 'NLS_NUMERIC_CHARACTERS = '',.''')
FROM DUAL;