Как узнать количество цифр оракула - PullRequest
2 голосов
/ 04 августа 2011

У меня есть таблица в oracle, которая выглядит следующим образом:

name              |     type    | nullable  
------------------------------------------
person_name       | varchar(20) | yes  
weight_coeficient | number      | yes
...

Как мне узнать сколько цифр имеет значение weight_coeficient ?Например:

3.0123456789 имеет 11 цифр ( точность = 11) и 10 цифр после десятичной дроби ( шкала = 10)

Isесть какая-либо команда / функция sql, которая делает это, что-то вроде GetPrecision( select.. ), которая возвращает 11?

Обратите также внимание, что определение таблицы не определяет масштаб и точность.Так что, насколько я знаю, максимальная точность применяется ко всем числам.Поэтому я не заинтересован в выяснении точности (= 48) определения, но в точности определенного значения в таблице.Возможно ли это просто с помощью команд оракула?

Заранее спасибо,
JP

Ответы [ 3 ]

5 голосов
/ 04 августа 2011

Как насчет ....

SELECT LENGTH(TRANSLATE(TO_CHAR(3.0123456789),'1234567890.-','1234567890')) 
FROM dual

Перевод просто удаляет нечисловые символы .-

0 голосов
/ 25 августа 2017

Используйте этот скрипт, чтобы сгенерировать соответствующие приведения для ваших данных.Я написал это, чтобы помочь перемещать данные NUMBER с неопределенной точностью и масштабированием в Oracle в Postgres через Kafka-Connect.Kafka-Connect позволяет выбирать данные для копирования в другую базу данных с помощью запроса, но, поскольку у нас не была установлена ​​точность чисел на стороне Oracle, Kafka-Connect вставлял все в Postgres как большое десятичное число.То есть Oracle 1 будет вставлен как 1.000000000 <30 десятичных знаков>.

SET SERVEROUTPUT ON;
DECLARE
   Q1    VARCHAR2 (4000 CHAR);
   str   VARCHAR2 (300 CHAR);
BEGIN
   FOR rec
      IN (SELECT  column_name AS column_name
            FROM all_tab_cols
           WHERE     owner = 'YOUR_SCHEMA'
                 AND TABLE_NAME = 'YOUR_TABLE'
                 AND DATA_TYPE = 'NUMBER')
   LOOP
      q1 :=
         'SELECT    REPLACE(''cast( ''
             || :1
             || '' as  NUMBER(''
             || TO_CHAR (MAX (LENGTH_OF_DECIMAL) + MAX (length_of_integer))
             || '',''
             || TO_CHAR (MAX (length_of_decimal))
             || ''))'',''NUMBER(0,0)'',''NUMBER'') as result
        FROM (SELECT charnum,
                     CASE
                        WHEN INSTR (charnum, ''.'') > 0
                        THEN
                           SUBSTR (charnum, INSTR (charnum, ''.'') + 1)
                        ELSE
                           NULL
                     END
                        AS decimal_part,
                     CASE
                        WHEN INSTR (charnum, ''.'') > 0
                        THEN
                           REPLACE (
                              REPLACE (
                                 SUBSTR (charnum,
                                         1,
                                         INSTR (charnum, ''.'') - 1),
                                 ''-'',
                                 ''''),
                              ''+'',
                              '''')
                        ELSE
                           REPLACE (REPLACE (charnum, ''-'', ''''), ''+'', '''')
                     END
                        AS integer_part,
                     CASE
                        WHEN INSTR (charnum, ''.'') > 0
                        THEN
                           LENGTH (
                              SUBSTR (charnum, INSTR (charnum, ''.'') + 1))
                        ELSE
                           0
                     END
                        AS length_of_decimal,
                     CASE
                        WHEN INSTR (charnum, ''.'') > 0
                        THEN
                           NVL (
                              LENGTH (
                                 REPLACE (
                                    REPLACE (
                                       SUBSTR (charnum,
                                               1,
                                               INSTR (charnum, ''.'') - 1),
                                       ''-'',
                                       ''''),
                                    ''+'',
                                    '''')),
                              0)
                        ELSE
                           NVL (
                              LENGTH (
                                 REPLACE (REPLACE (charnum, ''-'', ''''),
                                          ''+'',
                                          '''')),
                              0)
                     END
                        AS length_of_integer
                FROM (SELECT cast(col_name2 AS VARCHAR2 (50))
                                AS charnum
                        FROM YOUR_TABLE)) T1';

      q1 := REPLACE (q1, 'col_name2', rec.column_name);

      EXECUTE IMMEDIATE REPLACE (q1, 'col_name2', rec.column_name)
         INTO str
         USING rec.column_name;

      DBMS_OUTPUT.PUT_LINE (str);
   END LOOP;
END;
/

Контрольные примеры:

create table precision_tester(test_val number); 

- измените YOUR_TABLE на PRECISION_TESTER

(запуститьсценарий, проверьте вывод и удалите из Precision_tester после каждого теста)

insert into precision_tester(test_val) values (null); 
insert into precision_tester(test_val) values (+1);
insert into precision_tester(test_val) values (-1);
insert into precision_tester(test_val) values (-1.00);
insert into precision_tester(test_val) values (+1.001);
insert into precision_tester(test_val) values (+12.001);

Выводит следующие выходные данные в дБмс:

cast( TEST_VAL as  NUMBER)
cast( TEST_VAL as  NUMBER(1,0))
cast( TEST_VAL as  NUMBER(1,0))
cast( TEST_VAL as  NUMBER(1,0))
cast( TEST_VAL as  NUMBER(4,3))
cast( TEST_VAL as  NUMBER(5,3))
0 голосов
/ 19 декабря 2013

Небольшое улучшение заключается в использовании:

length(to_char(:number)) - coalesce(length(translate(to_char(:number), 'x1234567890', 'x')), 0)

Когда вы to_char вставляете 'E' для экспоненциального или другого символа группировки или десятичного разделителя, он все равно будет работать.

...