46 votes

Oracle - Pourquoi le zéro initial d'un nombre disparaît-il lorsqu'on le convertit en TO_CHAR

En Oracle, lors de la conversion d'un nombre avec un zéro initial en caractère, pourquoi le nombre initial disparaît-il ? Cette logique est-elle spécifique à Oracle ou spécifique à SQL ?

Exemple :

SÉLECTIONNER TO_CHAR(0.56) DE DUAL ;
/* Résultat = .56 */

56voto

Vadzim Points 4460

Je cherchais un moyen de formater les nombres sans espaces, points, zéros non signficatifs (sauf un zéro initial pour les nombres inférieurs à 1 qui doit être présent).

Il est frustrant qu'un formatage aussi courant soit difficile à réaliser dans Oracle.

Même Tom Kyte ne propose qu'une solution longue et compliquée comme celle-ci :

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

Mais j'ai pu trouver une solution plus courte qui ne mentionne la valeur qu'une seule fois :

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

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

select 
    to_char(num, 'FM99.99') mauvais_point_début,
    to_char(num, 'FM90.99') mauvais_point_fin,
    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;

    | MAUVAIS_POINT_DEBUT | MAUVAIS_POINT_FIN | 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 existe une approche de raccourcissement avec une fonction d'aide personnalisée :

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

Mais les fonctions PL/SQL personnalisées ont un surcoût significatif en performances qui ne sont pas adaptées aux requêtes lourdes.

43voto

DCookie Points 22921

C'est le formatage par défaut fourni par Oracle. Si vous voulez des zéros en tête en sortie, vous devrez fournir explicitement le format. Utilisez :

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

ou même :

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

Il en va de même pour les zéros en fin :

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(nombre, format)

12voto

mkb Points 21

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

La seule solution que j'ai trouvée 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             résultat de la requête
0.8            0.8  --pas quelque chose comme .80
10             10  --pas quelque chose comme 10.00

6voto

rawberto Points 73

Cela ne fonctionne que pour les chiffres inférieurs à 1.

sélectionnez to_char(12.34, '0D99') de dual;
-- Résultat: #####

Cela ne fonctionnera pas.

Vous pouvez faire quelque chose comme ceci mais cela entraîne des espaces vides en tête :

sélectionnez to_char(12.34, '999990D99') de dual;
-- Résultat: '     12,34'

En fin de compte, vous pourriez ajouter un TRIM pour vous débarrasser à nouveau des espaces blancs mais je ne considérerais pas cela comme une solution adéquate non plus...

sélectionnez trim(to_char(12.34, '999990D99')) de dual;
-- Résultat: 12,34

Encore une fois, cela ne fonctionnera que pour les chiffres avec un maximum de 6 chiffres.

Édition : Je voulais ajouter cela sous forme de commentaire à la suggestion de DCookie mais je ne peux pas.

1voto

Joël Points 1

Devrait fonctionner dans tous les cas :

SELECT regexp_replace(0.1234, '^(-?)([.,])', '\10\2') FROM dual

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X