Oracle 将带括号的数字解析为负数

Oracle 将带括号的数字解析为负数,oracle,oracle11gr2,Oracle,Oracle11gr2,我有一个VARCHAR2,它是通过解析最终用户上传的CSV文件(可能是从Microsoft Excel转换而来)来填充的。其中一列必须是美元金额,我们希望程序接受最明确的数字金额(正数或负数),但拒绝任何看起来不像数字的内容(例如,如果用户上传了错误的电子表格) 要接受的值: 12345.6789 12345.67 12345.6 12345. 12345 12,345.67 $12345.67 -12345.67 -12,345.67 (12,345.67) 要拒绝的值: FRED 12%3

我有一个VARCHAR2,它是通过解析最终用户上传的CSV文件(可能是从Microsoft Excel转换而来)来填充的。其中一列必须是美元金额,我们希望程序接受最明确的数字金额(正数或负数),但拒绝任何看起来不像数字的内容(例如,如果用户上传了错误的电子表格)

要接受的值:

12345.6789
12345.67
12345.6
12345.
12345
12,345.67
$12345.67
-12345.67
-12,345.67
(12,345.67)
要拒绝的值:

FRED
12%345
BLAH123
£12345.67
可转让*:

(12345.67
12)345.67
12$345.67
1,23,4,5.67
12,345.67-
12 345.67
这是我们之前的代码,它没有涵盖所有情况:

TO_NUMBER(TRANSLATE(val,'0$,','0'))
如果出现异常(
VALUE\u ERROR
ORA-01858
“非数字字符”),我们会向用户报告适当的错误消息。它正确处理除括号外的所有上述情况

*(可以协商,因为我不想编写一段长达一页的代码来尝试处理每一种可能的排列;它需要可维护并处理用户可能使用的更可能的格式)

TL;DR有一个PR number格式元素用于显示带括号的负数(实际上),但它不适用于将字符串转换为数字的TO_number


以下是我迄今为止的天真方法:

TO_NUMBER(
   RTRIM(LTRIM(
     TRANSLATE(val,'0$ ','0')
     ,'('),')')
   ,'999999999999999999990D000000'
   ,'NLS_NUMERIC_CHARACTERS=''.,''')
* CASE WHEN val LIKE '(%)' THEN -1 ELSE 1 END