Печать
Категория: Вопросы и ответы Oracle
Просмотров: 11093

При попытке вывести в SQLPlus дробное число большее 0 и меньшее 1 пропадает лидирующий ноль:

SQL> SELECT 0.0001 C1 FROM dual;
        C1
----------
     .0001

Тот же результат и при явном преобразовании NUMBER в VARCHAR2 с помощью функции TO_CHAR:

SQL> SELECT TO_CHAR(0.0001) C1 FROM dual;
C1
-----
.0001

Если указать в функции TO_CHAR формат числа, то лидирующий ноль появляется:

SQL> SELECT TO_CHAR(0.0001, '90.9999') C1 FROM dual;
C1
--------
  0.0001

И всё бы хорошо, но хотелось бы избавиться от конечных нолей в отображаемой дробной части:

SQL> SELECT TO_CHAR(0.1, '90.9999') C1 FROM dual;
C1
--------
  0.1000

В этом нам поможет модификатор формата числа FM, который добавляет конечные пробелы вместо нолей до указанной ширины:

SQL> SELECT TO_CHAR(0.1, 'FM90.9999') C1 FROM dual;
C1
--------
0.1

Единственной неприятностью в этом случае, является то, что при отображении целых чисел остаётся разделитель целой и дробной частей числа (в нашем случае точка):

SQL> SELECT TO_CHAR(1, 'FM90.9999') C1 FROM dual;
C1
--------
1.

Впрочем, он легко убирается функцией RTRIM:

SQL> SELECT RTRIM(TO_CHAR(1, 'FM90.9999'),  '.') C1 FROM dual;
C1
--------
1

Конечно, использование формата числа в функции TO_CHAR бывает не всегда удобно. Действие это довольно трудоёмкое. Велика вероятность ошибки в выборе разрядности формата. Если такой способ не подходит, то проблему можно решить с помощью DECODE:

SQL> SELECT DECODE(INSTR(TO_CHAR(0.001), '.'), 1 , '0' || TO_CHAR(0.001), 
TO_CHAR(0.001)) C1 FROM dual;
C1
-----
0.001 

или с помощью CASE:

SQL> SELECT CASE INSTR(TO_CHAR(0.001), '.') WHEN 1 THEN '0' || TO_CHAR(0.001) 
ELSE TO_CHAR(0.001) END C1 FROM dual;
C1
-----
0.001

Но ещё лучше создать функцию добавляющую ноль:

SQL> CREATE FUNCTION leadzero(p1 IN NUMBER)
  2   RETURN VARCHAR2 
  3   IS
  4   BEGIN
  5     IF INSTR(TO_CHAR(p1), '.') = 1 THEN
  6       RETURN '0' || TO_CHAR(p1);
  7     ELSE
  8       RETURN TO_CHAR(p1);
  9     END IF;  
 10   END;
 11  /
Function created.

Проверяем:

SQL> SELECT leadzero(0.0001) C1 FROM dual;
C1
---------------------------
0.0001