Oracle - pourquoi le zéro principal d'un nombre disparaît-il lors de sa conversion en CHAR

dans Oracle, lors de la conversion d'un nombre avec un zéro principal à un caractère, pourquoi est-ce que le nombre principal disparaît? Est-ce que cette logique est spécifique à Oracle, ou spécifique à SQL?

exemple:

SELECT TO_CHAR(0.56) FROM DUAL;
/* Result = .56 */
29
demandé sur contactmatt 2011-07-14 19:17:19

5 réponses

C'est le formatage par défaut fourni par Oracle. Si vous voulez des zéros de tête sur la sortie, vous aurez besoin de fournir explicitement le format. Use:

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

ou même:

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

il en est de même pour les zéros suivants:

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

VAL
------
 0.560

la forme générale de la fonction de conversion TO_CHAR est:

TO_CHAR (numéro, format )

30
répondu DCookie 2011-07-14 15:34:18

je cherchais un moyen de formater les nombres sans les mener ou les suivre espaces , les périodes, les zéros (sauf un zéro en tête pour les nombres inférieurs à 1 qui devraient être présents).

c'est frustrant que ce formatage le plus courant ne puisse pas être facilement réalisé dans Oracle.

Even Tom Kyte a seulement suggéré une solution longue et compliquée comme ceci:

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

mais j'étais capable de trouver une solution plus courte qui ne mentionne la valeur qu'une seule fois:

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

Ce fonctionne comme prévu pour toutes les valeurs possibles:

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 |

toujours à la recherche d'une solution encore plus courte.

il y a un raccourcissement approarch avec fonction custom helper:

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

mais les fonctions personnalisées pl/sql ont des performances significatives au-dessus de qui ne sont pas convient pour les requêtes lourdes.

17
répondu Vadzim 2017-05-23 12:03:02

semble comme la seule façon d'obtenir décimal dans une forme jolie (pour moi) nécessite un certain code ridicule.

La seule solution que j'ai obtenu jusqu'à présent:

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

xy est un décimal.

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

veuillez répondre à cette question s'il y a une option de format réel pour cela.

5
répondu mkb 2017-08-17 18:56:59

qui ne fonctionne Que pour les nombres inférieurs à 1.

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

ça ne marchera pas.

vous pourriez faire quelque chose comme cela, mais cela se traduit dans les espaces blancs de premier plan:

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

en fin de compte, vous pourriez ajouter une garniture pour se débarrasser des espaces à nouveau, mais je ne considérerais pas que la bonne solution soit non plus...

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

encore une fois, cela ne fonctionnera que pour les numéros à 6 chiffres max.

Edit: je voulais ajouter ceci comme commentaire sur la suggestion de DCookie mais je ne peux pas.

3
répondu rawberto 2014-05-21 12:43:17

Essayez ceci pour éviter to_char limites:

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
répondu Tadas Balaišis 2016-05-31 11:47:55