在Oracle中,当将一个带有前导零的数字转换为字符时,为什么前导数字会消失?这是Oracle特有的逻辑,还是SQL特有的逻辑?示例:
SELECT TO_CHAR(0.56) FROM DUAL; /* Result = .56 */
ac1kyiln1#
我一直在寻找一种方法来格式化数字,而不带前导或尾随spaces、句点、零(除了应该存在的小于1的数字的一个前导零)。令人沮丧的是,在Oracle中无法轻松实现这种最常见的格式化。即使是汤姆·凯特也只建议了这样一种冗长复杂的变通办法:
case when trunc(x)=x then to_char(x, 'FM999999999999999999') else to_char(x, 'FM999999999999999.99') end x
但我找到了一个简短的解决方案,只提到了一次价值:
rtrim(to_char(x, 'FM999999999999990.99'), '.')
对于所有可能的值,这都按预期工作:
select to_char(num, 'FM99.99') wrong_leading_period, to_char(num, 'FM90.99') wrong_trailing_period, rtrim(to_char(num, 'FM90.99'), '.') correct from ( select num from (select 0.25 c1, 0.1 c2, 1.2 c3, 13 c4, -70 c5 from dual) unpivot (num for dummy in (c1, c2, c3, c4, c5)) ) sampledata; | WRONG_LEADING_PERIOD | WRONG_TRAILING_PERIOD | CORRECT | |----------------------|-----------------------|---------| | .25 | 0.25 | 0.25 | | .1 | 0.1 | 0.1 | | 1.2 | 1.2 | 1.2 | | 13. | 13. | 13 | | -70. | -70. | -70 |
仍在寻找更短的解决方案。有一个带有自定义助手功能的缩短方法:
create or replace function str(num in number) return varchar2 as begin return rtrim(to_char(num, 'FM999999999999990.99'), '.'); end;
但是custom pl/sql functions have significant performace overhead不适合于繁重的查询。
inb24sb22#
这是Oracle提供的默认格式。如果希望在输出中使用前导零,则需要显式提供该格式。用途:
SELECT TO_CHAR(0.56,'0.99') FROM DUAL;
或者甚至:
SELECT TO_CHAR(.56,'0.99') FROM DUAL;
对于尾随零也是如此:
SQL> SELECT TO_CHAR(.56,'0.990') val FROM DUAL; VAL ------ 0.560
TO_CHAR转换函数的一般形式为:TO_CHAR(数字,格式)
lc8prwob3#
似乎唯一的方法来获得十进制在一个漂亮的(对我来说)形式需要一些荒谬的代码。到目前为止我得到的唯一解决办法是:
CASE WHEN xy>0 and xy<1 then '0' || to_char(xy) else to_char(xy)
xy是小数。
xy
xy query result 0.8 0.8 --not sth like .80 10 10 --not sth like 10.00
dxpyg8gm4#
这只对小于1的数字有效。
select to_char(12.34, '0D99') from dual; -- Result: #####
这样不行您可以这样做,但这会导致前导空格:
select to_char(12.34, '999990D99') from dual; -- Result: ' 12,34'
最后,你可以添加一个TRIM来再次去除空格,但我也不认为这是一个合适的解决方案...
select trim(to_char(12.34, '999990D99')) from dual; -- Result: 12,34
同样,这只适用于最多6位数的数字。编辑:我想把这个作为对DCookie建议的评论,但我不能。
31moq8wy5#
尝试以下操作以避免to_char限制:
SELECT regexp_replace(regexp_replace(n,'^-\'||s,'-0'||s),'^\'||s,'0'||s) FROM (SELECT -0.89 n,RTrim(1/2,5) s FROM dual);
lkaoscv76#
应在所有情况下工作:
SELECT regexp_replace(0.1234, '^(-?)([.,])', '\10\2') FROM dual
ztyzrc3y7#
如果数字类似,请尝试以下格式例1假设像10.1这样数字,如果应用下面的格式,它将是10.10例2假设数字像.02,如果应用下面的格式,它将是0.02例3假设像0.2这样数字,如果应用下面的格式,它将是0.20to_char(舍入(到_数字(列名)/10000000,2),'999999999990 D99')作为列名
xzlaal3s8#
如果您所在的国家/地区支持逗号表示十进制,请使用以下格式:
SELECT regexp_replace( regexp_replace(to_char(YOUR_NUMBER), '^,', '0,'), -- Positives '^-,', '-0,') -- Negatives
否则,如果您所在的国家/地区支持点表示小数,请使用以下代码:
SELECT regexp_replace( regexp_replace(to_char(YOUR_NUMBER), '^.', '0.'), -- Positives '^-.', '-0.') -- Negatives
8条答案
按热度按时间ac1kyiln1#
我一直在寻找一种方法来格式化数字,而不带前导或尾随spaces、句点、零(除了应该存在的小于1的数字的一个前导零)。
令人沮丧的是,在Oracle中无法轻松实现这种最常见的格式化。
即使是汤姆·凯特也只建议了这样一种冗长复杂的变通办法:
但我找到了一个简短的解决方案,只提到了一次价值:
对于所有可能的值,这都按预期工作:
仍在寻找更短的解决方案。
有一个带有自定义助手功能的缩短方法:
但是custom pl/sql functions have significant performace overhead不适合于繁重的查询。
inb24sb22#
这是Oracle提供的默认格式。如果希望在输出中使用前导零,则需要显式提供该格式。用途:
或者甚至:
对于尾随零也是如此:
TO_CHAR转换函数的一般形式为:
TO_CHAR(数字,格式)
lc8prwob3#
似乎唯一的方法来获得十进制在一个漂亮的(对我来说)形式需要一些荒谬的代码。
到目前为止我得到的唯一解决办法是:
xy
是小数。dxpyg8gm4#
这只对小于1的数字有效。
这样不行
您可以这样做,但这会导致前导空格:
最后,你可以添加一个TRIM来再次去除空格,但我也不认为这是一个合适的解决方案...
同样,这只适用于最多6位数的数字。
编辑:我想把这个作为对DCookie建议的评论,但我不能。
31moq8wy5#
尝试以下操作以避免to_char限制:
lkaoscv76#
应在所有情况下工作:
ztyzrc3y7#
如果数字类似,请尝试以下格式
例1假设像10.1这样数字,如果应用下面的格式,它将是10.10
例2假设数字像.02,如果应用下面的格式,它将是0.02
例3假设像0.2这样数字,如果应用下面的格式,它将是0.20
to_char(舍入(到_数字(列名)/10000000,2),'999999999990 D99')作为列名
xzlaal3s8#
如果您所在的国家/地区支持逗号表示十进制,请使用以下格式:
否则,如果您所在的国家/地区支持点表示小数,请使用以下代码: