我有一个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_ERROR
或ORA-01858
"非数字字符"),我们会向用户报告合适的错误消息。它正确处理除括号外的所有上述情况。
* (可协商,因为我不想编写一页长的代码来尝试处理所有可能的排列;它需要可维护并处理用户可能使用的更可能的格式)
TL; DR 有一个PR编号格式元素,用于显示带括号的负数(实际上<>),但它不适用于TO_NUMBER将字符串转换为数字。
答案 0 :(得分:1)
到目前为止,这是我天真的做法:
TO_NUMBER(
RTRIM(LTRIM(
TRANSLATE(val,'0$ ','0')
,'('),')')
,'999999999999999999990D000000'
,'NLS_NUMERIC_CHARACTERS=''.,''')
* CASE WHEN val LIKE '(%)' THEN -1 ELSE 1 END