动态 格式化数值的精度(小数点位数)问题
问题描述:
数据库中对数据采取放大成整数的方式进行存储,比如一个数据,其值为 1.23, 则将它存到数据库中精度 preci 为 2,value 为 123(=1.23 * 10^2),即 value 是经过 放大 10 的精度(preci)次方倍 之后存储的,已达到数据库只存整数。这样的 value 有很多,精度没有规律,但保证存储到数据中是正确的放大之后的值和它对应的精度。
目前,获得了数据(value)和这个数据对应的精度(preci),对数据格式化的这个过程我也希望在oracle 中完成。有没有什么好的方法在 oracle 中将这个 value 还原到它本来状态(值和精度都要一致)。
我目前的做法很傻,用到了 DECODE,
即 decode(value, 1, to_char(value / power(10, 1), 'FM999999990.0'), 2, to_char(value / power(10, 2), 'FM999999990.00'), ..., value) ,... 为可能的其他精度。
对 oracle 数据库不熟悉,不会使用,不知道有没有更简便的方法,不使用这么多的check。而且不知道 decode 对性能有没有什么影响。我前面生成 value 和 preci 也用到了 decode。
请各位指导,谢谢!!!
------最佳解决方案--------------------1、数据库里面加一列,格式化输出格式,在数据插入的时候维护一下把格式固定一下
因为你把数据变成整数的过程应该也会得到这个数据,既然得到了就把它存下来,方便后面使用
2、对于数据的更新,可以利用触发器,自动维护该格式字段
如果系统不允许使用触发器,那就在应用程序上增加对该字段的维护
其他暂时没有想到什么好办法。
--对于你对decode函数效率的疑问是对的,频繁大量使用decode函数是会影响效率,会消耗cpu
但是一般简单使用在目前的硬件水平下,没太大影响。
------其他解决方案--------------------SELECT STR,RPAD(1,STR1+1,'0'),STR1,STR*RPAD(1,STR1+1,'0') AS RESULT FROM (SELECT '1.258' AS STR ,LENGTH(SUBSTR('1.258',INSTR('1.258','.')+1,3)) AS STR1 FROM DUAL)
------其他解决方案--------------------上面的有问题。
SELECT STR,RPAD(1,STR1+1,'0'),STR1,STR*RPAD(1,STR1+1,'0') AS RESULT FROM (SELECT '1.258' AS STR ,LENGTH(SUBSTR('1.258',INSTR('1.258','.')+1)) AS STR1 FROM DUAL)
------其他解决方案--------------------楼上的都是大神啊
------其他解决方案--------------------WITH TEST AS (
SELECT '1.1' AS T FROM DUAL
UNION ALL
SELECT '1.12' AS T FROM DUAL
UNION ALL
SELECT '1.123' AS T FROM DUAL
UNION ALL
SELECT '1.1234' AS T FROM DUAL
UNION ALL
SELECT '1.12345' AS T FROM DUAL
UNION ALL
SELECT '1.123456' AS T FROM DUAL
)
SELECT T,RPAD(1,STR1+1,'0'),STR1,T*RPAD(1,STR1+1,'0') AS RESULT FROM (SELECT T ,LENGTH(SUBSTR(T,INSTR(T,'.')+1)) AS STR1 FROM TEST)
===============================================
1.1 10 1 11
1.12 100 2 112
1.123 1000 3 1123
1.1234 10000 4 11234
1.12345 100000 5 112345
1.123456 1000000 6 1123456
------其他解决方案--------------------WITH TEST AS (
SELECT '123456' AS STR1,'2' AS STR2 FROM DUAL
UNION ALL
SELECT '123456' AS STR1,'3' AS STR2 FROM DUAL
UNION ALL
SELECT '123456' AS STR1,'4' AS STR2 FROM DUAL
)
SELECT STR1,STR2,STR1/RPAD(1,STR2+1,'0') AS STR3 FROM TEST
===============================
123456 2 1234.56
123456 3 123.456
123456 4 12.3456
------其他解决方案--------------------多谢各位啦!哈哈,看了之后懂了些东西!