最好的方法是
First Solution 将数字转换为列
要么
第二个解决方案 用数字转换您查询中的数据而不是获取数据...
例
select max(col1) from(
select to_number(numbers) as col1 from table ) d
Run Code Online (Sandbox Code Playgroud)
它必须是这样的,因为如果你调用TO_NUMBER()之前MAX(),它会按字母顺序排序,然后999999是大于100000000000.请注意使用TO_NUMBER()为VARCHAR2列须支付INVALID_NUMBER异常的风险,应包含任何非数字字符的列.这就是首选提出的解决方案的首选原因.
在Oracle中,NUMBER类型包含基本100个浮点值,其精度为38位有效数字,最大值为9999 ...(38 9)x 10 ^ 125.有两个问题 - 第一个问题是NUMBER是否可以包含从256个字符串转换的值,第二个问题是是否可以区分两个数字术语中"接近"的值.
让我们从一个256个字符的字符串开始,然后尝试将其转换为数字.显而易见的事情是:
SELECT TO_NUMBER('9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999') AS VAL
FROM DUAL;
Run Code Online (Sandbox Code Playgroud)
执行上面我们得到:
ORA-01426: numeric overflow
Run Code Online (Sandbox Code Playgroud)
我们期待早些时候注意到这一点.NUMBER可以处理的最大指数是125 - 这里我们尝试转换256位有效数字的值.NUMBER无法处理此问题.如果我们将位数减少到125,如下:
SELECT TO_NUMBER('99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999') AS VAL
FROM DUAL;
Run Code Online (Sandbox Code Playgroud)
它工作正常,我们的答案是1E125.
< blink >
哇!等待!!什么???答案是1 x 10 ^ 125 ??? 那9个人怎么样?!?!?!?
记得早些时候我曾提到Oracle NUMBER是一个浮点值,最大精度为38,最大指数为125.从TO_NUMBER 125 9的角度来看,所有串联在一起无法准确表示 - 数字太多(记住,最大精度为38(稍后会详细介绍)).所以它尽可能绝对最好 - 它转换前38位数(所有这些都是9位数)然后说"我应该如何最好地将这个数字转化为结果A"代表输入和B)尽可能接近我能得到我给的东西吗?" 在这种情况下,它查看数字39,看到它是9,并决定向上舍入.由于所有其他数字也是9位数,它会继续整齐地四舍五入,直到最后以1作为剩余的尾数位数.
*后来,回到牧场......*
好的,早些时候我提到NUMBER的精度为38位.这并不完全正确 - 它实际上可以区分精度高达40位的值,至少有时候,如果风是正确的,并且你正在走下坡路.这是一个例子:
SELECT CASE
WHEN to_number('9999999999999999999999999999999999999999') >
to_number('9999999999999999999999999999999999999998')
THEN 'Greater'
ELSE 'Not greater'
END AS VAL
FROM DUAL;
Run Code Online (Sandbox Code Playgroud)
这两个值每个都有40位数(计数留给非常无聊的读者:-).如果执行上述操作,您将返回'更大',表示两个40位数值的比较成功.
现在为了一些乐趣.如果你为每个字符串添加一个额外的'9',使得41位数值,并重新执行该语句,它将返回'Not greater'.
< blink >
等待!什么??哇!这些价值观明显不同!即使是TotalFool(tm)也能看到!!
这里的问题是41位数字超过了NUMBER类型的精度,因此当TO_NUMBER发现它有一个值时,它开始丢弃右侧的数字.因此,尽管这两个非常大的数字对你我来说显然是不同的,但一旦它们被折叠,旋转,肢解和转换,它们就完全不同了.
那么,这里有什么需要呢?
1 - 对于OP的原始问题 - 除了使用NUMBER之外,您还必须提出另一种比较数字字符串的方法,因为Oracle的NUMBER类型不能保存256位数值.我建议您通过确保所有值都是256位数字来规范化字符串,根据需要在左侧添加零,然后字符串比较应该可以正常工作.
2 - 浮点数通过否定来证明(你最喜欢的神灵/神灵)的存在,因为它们显然是(你最喜欢的邪恶化身).每当你和他们一起工作时(我们都必须迟早),你应该记住,他们是邪恶邪恶的副产品,等待你最不期望的时候抨击你.
3 -有否点三!(对于那些能够识别而不诉诸于颅外搜索引擎的人来说,还有额外的功劳:-)
分享和享受.
| 归档时间: |
|
| 查看次数: |
2980 次 |
| 最近记录: |