2回ソートする必要があります(nullの戻り値を許可するために、regexp_replaceからregexp_substrに変更したことに注意してください)
with
a as (
select 'PROD_1' product from dual union all
select 'PROD_10' product from dual union all
select 'PROD_2' product from dual union all
select 'PROD_3' product from dual union all
select 'PROD_4' product from dual union all
select 'PROD_5' product from dual union all
select 'PROD_6' product from dual union all
select 'PROD_7' product from dual union all
select 'PROD_8' product from dual union all
select 'PROD_9' product from dual union all
select 'DECEAD_1' product from dual union all
select 'DECEAD_10' product from dual union all
select 'DECEAD_2' product from dual union all
select 'DECEAD_20' product from dual union all
select 'TREE_FROG' product from dual
)
select PRODUCT
, regexp_substr(product,'[^[:digit:]]*') --return all non numeric
, regexp_substr(product,'[0-9]+')
from a
order by regexp_substr(product,'[^[:digit:]]*') ,
TO_NUMBER(regexp_substr(product,'[0-9]+')) --note explicit numeric cast
;