2011-07-14 38 views

Respuesta

29

Es el formato predeterminado que Oracle ofrece. Si desea obtener ceros a la salida, deberá proporcionar explícitamente el formato. Uso:

SELECT TO_CHAR(0.56,'0.99') FROM DUAL; 

o incluso:

SELECT TO_CHAR(.56,'0.99') FROM DUAL; 

Lo mismo es cierto para los ceros a la derecha:

SQL> SELECT TO_CHAR(.56,'0.990') val FROM DUAL; 

VAL 
------ 
0.560 

La forma general de la función de conversión TO_CHAR es:

TO_CHAR (número, format)

+3

la salida http://ss64.com/ora/syntax-numfmt.html para una buena lista de los diferentes formatos disponibles – jworrin

+0

número 1, gracias por eso, respuesta actualizada. – DCookie

+6

El problema con esta solución se produce cuando no tenemos el número exacto de dígitos después del punto decimal. ¿Qué podemos hacer en este caso? Una solución muy fea sería agregar un 'caso cuando myNum <1 luego agregarLeadingZero end case' y hacer lo mismo con números entre -1 y 0. Entonces ... ¿qué podemos hacer? –

3

que sólo funciona para los números de menos de 1.

select to_char(12.34, '0D99') from dual; 
-- Result: ##### 

Esto no funcionará.

Se podría hacer algo como esto, pero esto da lugar a espacios en blanco principales:

select to_char(12.34, '999990D99') from dual; 
-- Result: '  12,34' 

En última instancia, se podría añadir una MIC para deshacerse de los espacios en blanco de nuevo, pero yo no consideraría que una solución adecuada, ya sea. ..

select trim(to_char(12.34, '999990D99')) from dual; 
-- Result: 12,34 

Nuevamente, esto solo funcionará para números con un máximo de 6 dígitos.

Editar: Quería agregar esto como un comentario en la sugerencia de DCookie pero no puedo.

5

Parece que la única forma de obtener un decimal en una forma bonita (para mí) requiere un código ridículo.

La única solución que tengo hasta ahora:

CASE WHEN xy>0 and xy<1 then '0' || to_char(xy) else to_char(xy) 

xy es una decimial.

xy    query result 
0.8   0.8 --not sth like .80 
10    10 --not sth like 10.00 

Responda esta pregunta si existe una opción de formato real para esto.

14

Estaba buscando una forma de formatear números sin spaces, períodos, ceros iniciales o posteriores (excepto un cero a la izquierda para números menores a 1 que deberían estar presentes).

Esto es frustrante porque el formato más habitual no se puede lograr fácilmente en Oracle.

Incluso Tom Kyte only suggested long complicated workaround así:

case when trunc(x)=x 
    then to_char(x, 'FM999999999999999999') 
    else to_char(x, 'FM999999999999999.99') 
end x 

Pero yo era capaz de encontrar la solución más corta que menciona el valor de una sola vez:

rtrim(to_char(x, 'FM999999999999990.99'), '.') 

Este works as expected para todos los valores posibles:

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 | 

Todavía en busca de una solución aún más corta.

Hay un acortamiento approarch con función auxiliar personalizado:

create or replace function str(num in number) return varchar2 
as 
begin 
    return rtrim(to_char(num, 'FM999999999999990.99'), '.'); 
end; 

Pero custom pl/sql functions have significant performace overhead que no es adecuado para consultas pesadas.

+0

que me ha ayudado mucho. Thx –

+1

Para obtener más decimales y delimitador personalizado, utilicé 'RTRIM (TO_CHAR (x, 'FM99999999999999990D99999999999999', 'NLS_NUMERIC_CHARACTERS =' ',.' ''), ',')'. Este es el formato utilizado en la configuración regional checa. – Palec

1

Prueba esto para evitar to_char limitaciones:

SELECT 
regexp_replace(regexp_replace(n,'^-\'||s,'-0'||s),'^\'||s,'0'||s) 
FROM (SELECT -0.89 n,RTrim(1/2,5) s FROM dual); 
+1

utilizando dos regex_replace parece muy poco óptimo para mí. Y la pregunta original es más bien ¿Por qué ?, ¿no cómo? –

+2

Eso es mejor que to_char, porque no está limitado a un formato específico. Se escapa la situación ####### para números grandes, y se escapan ceros no deseados después de los decimales para el número entero. Simplemente agrega cero para los números de rango [-1; 1] que se ve incómodo en la representación nativa de Oracle. Es suficiente con solo una regexp_replace, si está seguro de que el número es positivo. –

Cuestiones relacionadas