案例1:SELECT TO_CHAR(12345.6789, '99999D99') FROM dual;
Output: 12345.67
案例2:SELECT TO_CHAR(12345.6789, '999D99') FROM dual;
Output: ######
案例3:SELECT TO_CHAR(12345, '99999D99') FROM dual;
Output: 12345.00
案例4:SELECT TO_CHAR(12345.1, '99999D99') FROM dual;
Output: 12345.10
这里的问题是,如果我们不知道小数点前有多少位数,那么如何管理正确的答案。[只有案例1,3,4可以使用TO_CHAR解决,但如何解决案例2。] < / p>
答案 0 :(得分:1)
在这种情况下,最简单的答案可能是根本不提供格式模型,而是将值截断或舍入到两位小数:
SELECT TO_CHAR(ROUND(12345.6789, 2)) as rounded,
TO_CHAR(TRUNC(12345.6789, 2)) as truncated
FROM dual;
ROUNDED TRUNCATED
-------- ---------
12345.68 12345.67
如果省略 fmt ,则 n 将转换为VARCHAR2值,其长度足以保留其有效数字。
否则,您需要提供一个格式模型,允许您的号码的最大大小;如果它不受限制,你需要36个9,小数分隔符和两个9。结果将填充空格,因此您可能还需要修剪它,具体取决于您将如何使用字符串值。
SELECT TO_CHAR(12345.6789, '999999999999999999999999999999999999D99') as val
FROM dual;
VAL
----------------------------------------
12345.68
你也可以通过使用截断值的长度灵活地做到这一点(即一旦删除了小数位):
SELECT TO_CHAR(12345.6789,
lpad('9', length(trunc(12345.6789)), '9') || 'D99') as val
FROM dual;
VAL
---------
12345.68
但是,当你让Oracle为你解决问题时,这看起来似乎不必要了。
但是,如果您希望小数显示尾随零,则可能需要使用该方法;但小数分隔符后面带零:
SELECT TO_CHAR(12345.6, lpad('0', length(trunc(12345.6)), '9') || 'D00') as val
FROM dual;
VAL
---------
12345.60
...解决了您添加的第3和第4个案例。我已经让它显示了小于1的值的前导零;在这种情况下生成的格式模型是'99990D00'
。 9的数量仍将根据您的号码大小而变化。
默认情况下,Oracle仍会在开头留出一个空格,表示潜在的减号。你可以使用the FM format modifier来避免这种情况:
SELECT TO_CHAR(12345.6, 'FM'
|| lpad('0', length(trunc(12345.6)), '9') || 'D00') as val
FROM dual;
VAL
--------
12345.60
答案 1 :(得分:0)
您始终可以使用输入中预期存在的最大位数。如果输入中的数字少于格式说明符,则无论如何都不会影响结果。例如,
select to_char(12323.5553,'99999D99') from dual
会产生,
123.56
答案 2 :(得分:0)
正如你所说,输入的长度是unknwon。那么为什么你会使用一个固定长度的格式化器来处理未知的事情呢?不行。从头开始将您的输入读取为String,并将其作为String或更好地操作 - BLOB。
好吧,做正确的舍入可能会很棘手。
因此,如果数字真的太大,最好检查一下你的数据,因为那会带来很多工作和麻烦。
如果不需要超过38位,您可以使用十进制或数字数据类型(如果您坚持使用格式化程序),请使用TM格式化程序。
SELECT to_char(cast(1234.456为十进制(*,2)),&#39; TM&#39;)为FROM双重
或接受其他海报上面给出的建议。