【发布时间】:2015-09-23 08:31:43
【问题描述】:
我使用TO_CHAR 函数将数字从0001 格式化为9999,并适应插入值的列大小(VARCHAR2(4))(即使值> 9999)。
我使用这样的函数:
TO_CHAR(n, 'FM0000')
有效的例子:
SELECT TO_CHAR(1, 'FM0000') FROM DUAL;
结果:0001
SELECT TO_CHAR(1234, 'FM0000') FROM DUAL;
结果:1234
但是当我用大于 9999 的值进行测试时,我得到一个额外的字符:
SELECT TO_CHAR(12345, 'FM0000') FROM DUAL;
结果:#####
SELECT TO_CHAR(123456, 'FM0000') FROM DUAL;
结果:#####
关于信息,我预期的结果是####(4 个字符)。
总结一下:
- 当要转换的值对应于预期的大小 (4) 时,转换后的值具有相同的长度 (4)
- 当要转换的值长于预期大小(5 或更多)时,转换后的值比预期长度多一个字符 (5)。
如何解释?
我在 https://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements004.htm#i170559https://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements004.htm#i170559 的 Oracle 文档中没有找到解释
我尝试了几个Oracle版本(9、10、11),结果都是一样的。
解决方法我发现是用 RPAD() 函数 RPAD(TO_CHAR(n,'FM0000'), 4) 截断结果,但我需要了解为什么 TO_CHAR 函数不够。
【问题讨论】:
-
SELECT TO_CHAR(-1, 'FM0000') FROM DUAL; -
您到底想达到什么目的?如果您选择大于 9999 的数字(例如 12345),您希望返回什么值?
-
如果您在 SQL*Plus 中使用 TO_CH。除了您想要的四个有效数字之外,它还必须允许值的符号。 (正如弗洛林的查询所示......)。您也可以尝试使用
'FMS000'来明确查看它的正值。您可以使用substr(to_char(...), -4)作为替代解决方法。 -
@Ollie 该值保存在两列中,一列在 VARCHAR2(4) 中(旧系统兼容性),另一列在 NUMBER 中(新系统)。这个想法是让旧系统在 1 到 9999 之间(没有负值)工作,新系统允许大于 9999 的值。在 VARCHAR(4) 列中,值的格式应为 0000,因此值如12345 可以保存为 '####' (在这种情况下它将由新系统处理)。
-
我现在明白了,
TO_CHAR(12345, '0000')已经返回#####,所以在这种情况下,FM将什么也不做,因为没有前导空格。