Regexp_replace WITH DECIMAL 返回错误 ORA-01722 "Invalid Number"

Regexp_replace WITH DECIMAL is returning error ORA-01722 "Invalid Number"

在 Oracle 中我有这样的代码:

regexp_replace(DESCRIPTION_FIELD, '[^0-9.]+', '') 

工作正常,但现在出现错误:

ORA-01722 "Invalid Number".

删除小数点可以修复此问题,但会从返回值中删除小数点。我猜最近添加了一些不良数据。解决方案?

如果您会话的 NLS_NUMERIC_CHARACTERS 的小数点设置错误,通常会出现此错误。

您可以使用此更改会话设置:

alter session set NLS_NUMERIC_CHARACTERS = '.,';

alter session set NLS_NUMERIC_CHARACTERS = ',.';

这将仅为您的当前会话设置小数点和组分隔符。

或者您的 select 语句中有一个更通用的解决方案,该解决方案将始终假定为“.”。作为来自 table 的数据中的小数点。并将显示您会话的带小数点的数字。

select to_number(regexp_replace(ESCRIPTION_FIELD, '[^0-9.]+', ''), '999999999999.99999', 'NLS_NUMERIC_CHARACTERS = ''.,''') from <your table>;

编辑

如果在字符串中找到更多小数点并且您可以接受跳过一些小数点,那么这可能有效。

select to_number(regexp_substr(regexp_replace(ESCRIPTION_FIELD, '[^0-9.]+', ''),'([0-9]*.[0-9]*)'), '999999999999.99999', 'NLS_NUMERIC_CHARACTERS = ''.,''') from <your table>;

regexp_replace() 没有产生那个错误;问题是当您将该替换的结果转换为数字时。例如,对于原始值 XYZ2626...266.88,您的模式返回 2626...266.88,而 to_number('2626...266.88') 抛出 ORA-01722。

by finding numbers with a format of "Some numbers, a decimal, then two numbers"

您可以寻找那个而不是试图排除其他字符:

with your_table (description_field) as (
  select 'No money value' from dual
  union all
  select 'Some sensible 98765.43 value' from dual
  union all
  select '01234-1234545 54.00' from dual
  union all
  select 'XYZ2626...266.88' from dual
  union all
  select 'ABC-123.45XYZ' from dual
  union all
  select 'ABC123.45XYZ6.78' from dual
)
select description_field,
  regexp_replace(DESCRIPTION_FIELD, '[^0-9.]+', '') as original,
  regexp_replace(DESCRIPTION_FIELD, '.*?((-?\d+\.\d{2})[^0-9]*)?$', '') as new
from your_table;

DESCRIPTION_FIELD            ORIGINAL             NEW                 
---------------------------- -------------------- --------------------
No money value                                                        
Some sensible 98765.43 value 98765.43             98765.43            
01234-1234545 54.00          01234123454554.00    54.00               
XYZ2626...266.88             2626...266.88        266.88              
ABC-123.45XYZ                123.45               -123.45             
ABC123.45XYZ6.78             123.456.78           6.78                

我允许使用负数,但您可能不想要这些...如果有多个潜在货币价值,它会取最后一个。

捕获组 (-?\d+\.\d{2}) 寻找一个可选的减号,后跟任意数量的数字,再后跟一个句点,然后正好是 2 位数字。但这本身并不能阻止后面的更多数字,所以它后面跟着 [^0-9]* 以确保不会发生这种情况。该组合包含在第二个分组中以允许它是可选的(后跟 ?)- 否则没有任何看起来像货币金额的值将不加改变地传递,这也可能会出错。