问题
I have a table where i have data with leading zeros for a column(number datatype). When i try to query the column in apex - SQL Workshop, it is not displaying the leading zero. So i need to manually convert to display value with leading zeros. But there is a problem while converting.
If i format explicitly using to_char
then it is affecting the normal value.
For example
select to_char(colA,'0.99') from tab1
will give me 0.87 when value is .87 but we do have values without decimal also. in that case it will give me ###. Basically i want to display value as it is(but add 0 if value is starting with decimal). It should not add trailing zero also.Is there any way to achieve this? For example, below will give 661.00. But it should not give. If it whole number, it should display the same value.
select to_char(661,'999G999G999G999G990D00MI') from dual
回答1:
You can get close with a mask like 'FM999999990D9999'
, with an appropriate number of 9s each side of the decimal to cover all values you might have.
with tab1 (cola) as (
select 0.87 from dual
union select 661 from dual
union select 661.87 res from dual
union select 1.5 res from dual
)
select cola, to_char(cola, 'FM999999990D9999')
from tab1;
COLA TO_CHAR(COLA,'F
---------- ---------------
.87 0.87
1.5 1.5
661 661.
661.87 661.87
The FM
removes trailing zeros and leading spaces (including a nominal space for a +/- sign).
To get rid of the trailing decimal marker too you need to trim it off:
with tab1 (cola) as (
select 0.87 from dual
union select 661 from dual
union select 661.87 res from dual
union select 1.5 res from dual
)
select cola, rtrim(to_char(cola, 'FM999999990D9999'), to_char(0, 'FMD'))
from tab1;
I've stuck with D
in both parts of that; you could use a fixed .
in both so you don't need the second to_char()
call to convert that, but you may want it to be controlled by the session - either way it needs to be consistent.
If you don't know how many 9s you need to include, you could generate a bespoke format mask for every number, based on how many digits there are before and after the decimal separator:
with tab1 (cola) as (
select 0.87 from dual
union all select 661 from dual
union all select 661.87 res from dual
union all select 1.5 res from dual
union all select 0.00045354543 from dual
)
select cola,
'FM' || lpad('0', length(trunc(cola)), '9')
|| case when trunc(cola) != cola
then 'D' || rpad('9', length(cola - trunc(cola)) - 1, '9')
end as format_mask,
to_char(cola,
'FM' || lpad('0', length(trunc(cola)), '9')
|| case when trunc(cola) != cola
then 'D' || rpad('9', length(cola - trunc(cola)) - 1, '9')
end) as result
from tab1;
COLA FORMAT_MASK RESULT
--------------- -------------------- --------------------
.87 FM0D99 0.87
661 FM990 661
661.87 FM990D99 661.87
1.5 FM0D9 1.5
.00045354543 FM0D99999999999 0.00045354543
This relies on implicit conversion but seems to work for positive, negative and zero. It doesn't need to trim the result because the decimal separator D is only included at all for non-integers.
回答2:
Think also your format mask is wrong D99 should help:
SQL> with a as
2 ( select 1/100 nb, '0.01' res from dual
3 union select 20 nb, '20' res from dual
4 union select 444/100 nb, '4.44' res from dual
5 union select 120/100 nb, '1.2' res from dual)
6 select nb, to_char(nb,'999G990D99') t_c, res from a
NB T_C RES
,01 0,01 0.01
1,2 1,20 1.2
4,44 4,44 4.44
20 20,00 20
回答3:
How about using a case statement in your query for the column in question?
Something like this:
select case
when INSTR(to_char(:test_no),'.') = 1
then replace(to_char(:test_no),'.','0.')
else to_char(:test_no)
end as 'test_no'
from dual
来源:https://stackoverflow.com/questions/51268758/values-are-not-displaying-with-leading-zero-in-oracle