You can do it without any regex, using the validate_conversion()
function.
Create the table with data
create table table1
(
id number generated as identity
column1 varchar2(50),
)
/
INSERT INTO TABLE1 (COLUMN1) VALUES ('01A');
INSERT INTO TABLE1 (COLUMN1) VALUES ('02A');
INSERT INTO TABLE1 (COLUMN1) VALUES ('1.30');
INSERT INTO TABLE1 (COLUMN1) VALUES ('1,30');
INSERT INTO TABLE1 (COLUMN1) VALUES ('100000');
INSERT INTO TABLE1 (COLUMN1) VALUES (' ');
INSERT INTO TABLE1 (COLUMN1) VALUES (null);
Do the conversion
select
column1 as original_value,
validate_conversion(replace(column1, ',', '.') as number, '999990D00', 'NLS_NUMERIC_CHARACTERS = ''.,''') as is_the_value_convertable,
case
when validate_conversion(replace(column1, ',', '.') as number, '999990D00', 'NLS_NUMERIC_CHARACTERS = ''.,''') = 1
then nvl(cast(replace(column1, ',', '.') as number, '999990D00', 'NLS_NUMERIC_CHARACTERS = ''.,'''), 0)
else 0
end as converted_value
from
table1;
Use the appropriate NLS parameter(s) and number format that is appropriate for your use case.
Note: the first two columns are just there for clarity, you can omit them. The second column shows how the validation function works. It outputs 1 when it's possible to convert the value without error, and zero otherwise (instead of an error).
The third column is to do the actual conversion, using the validation function to determine whether it should try the conversion, or just output 0
. It's wrapped in an nvl()
because otherwise inputting a null
would return a null
, instead of the 0
that you want in the case where the conversion is not possible.
Documentation: https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/VALIDATE_CONVERSION.html#GUID-DC485EEB-CB6D-42EF-97AA-4487884CB2CD