您的格式模型仍然必须允许值的符号.没有办法向TO_CHAR()表明它永远不会是负数(如果你的值实际上是这种情况).即使使用4位数字,格式允许允许五个字符,您可以从列标题中看到:
SQL> SELECT TO_CHAR(1234, 'FM0000') FROM DUAL;
TO_CH
-----
1234
请注意,列标题是TO_CH,它是五个字符,而不是四个字符.如果您有一个负数(如Florin建议的那样),您需要额外的空间:
SQL> SELECT TO_CHAR(-1234, 'FM0000') FROM DUAL;
TO_CH
-----
-1234
如果没有FM修饰符,则返回的字符串中的前导空格为正值,因此LENGTH(TO_CHAR(1234,’0000′))为5但LENGTH(TO_CHAR(1234,’FM0000′))为4,因为前导空格(通常使列中的值右对齐)被抑制.如果为负值,则返回字符串的长度为5.格式模型确定返回的数据类型是varchar2(5)以允许符号,即使您知道永远不会有负值 – 格式模型也没有任何方法可以反映这一点.
如果您强制显示符号,也可以使用正值查看它:
SQL> SELECT TO_CHAR(1234, 'FMS0000') FROM DUAL;
TO_CH
-----
+1234
在TO_CHAR调用中,您无法做任何事情.作为RPAD解决方法的替代方法,您可以使用SUBSTR仅获取格式化字符串的最后四个字符:
SQL> SELECT SUBSTR(TO_CHAR(12345, 'FM0000'), -4) FROM DUAL
SUBSTR(TO_CHAR(1
----------------
####
但如果你确实有负值,你就会失去这个标志:
SQL> SELECT SUBSTR(TO_CHAR(-1234, 'FM0000'), -4) FROM DUAL
SUBSTR(TO_CHAR(-
----------------
1234
使用你的RPAD你保持标志但丢失了第四个有效数字:
SQL> SELECT RPAD(TO_CHAR(-1234, 'FM0000'), 4) FROM DUAL
RPAD(TO_CHAR(-12
----------------
-123
这也不好.你可能不必处理负数;但如果您处理的数字大于预期(即,当您只期望< = 9999时,您得到的数字> = 10000)那么我不确定您是否可以确定您不会看到(无效?)在某些时候的负数.这似乎是一个数据问题,而不是格式问题,无论如何在某种程度上. 根据你对Ollie的评论,对于未来的代码维护者来说,另一种可能更明确和更明显的方法是在CASE中拼写出来:
SELECT CASE WHEN n BETWEEN 0 AND 9999 THEN TO_CHAR(n, 'FM0000') ELSE '####' END FROM DUAL
如果你愿意,这也允许你将字符串列保留为null或使用其他一些魔术值而不是####.
另一种修改价值的方法,也可能更清楚,就是使用CAST:
SQL> SELECT CAST(TO_CHAR(12345, 'FM0000') AS VARCHAR2(4)) FROM DUAL;
CAST
----
####