【问题标题】:How to find out the number of digits of an oracle number如何找出预言机号码的位数
【发布时间】:2011-10-19 23:06:54
【问题描述】:

我在 oracle 中有一个如下所示的表:

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

如何计算 weight_coeficient 的值 有多少位?例如:

3.0123456789 有 11 位数字 (precision = 11) 和小数点后 10 位数字 (scale = 10)

是否有任何 sql 命令/函数可以执行此操作,例如返回 11 的 GetPrecision( select.. )

还要注意,表格的定义没有指定比例和精度。据我所知,最大精度适用于所有数字。所以我对找出定义的精度(= 48)不感兴趣,而是找出表中特定值的精度。仅使用 oracle 命令可以吗?

提前谢谢你,
JP

【问题讨论】:

    标签: oracle plsql precision


    【解决方案1】:

    怎么样....

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

    翻译只是删除非数字字符.-

    【讨论】:

    • 感谢您的回答。但3.0123456789 就是一个例子。考虑到表名是Coeficients,如何调整您编写的代码以使用weight_coeficient?我会期待像SELECT LENGTH(TRANSLATE(Select weight_coeficient from Coeficients where name = 'John Paul'),'1234567890.-','1234567890')) FROM dual 这样的东西。但这不起作用。对不起..我不太擅长 sql sintax
    • @John Paul:SELECT LENGTH(TRANSLATE(weight_coeficient),'1234567890.-','1234567890')) from Coeficients where name = 'John Paul'; 会更好
    • @Allan:很好的提示,但你有一个额外的括号。我觉得应该是SELECT LENGTH(TRANSLATE(weight_coeficient,'1234567890.-','1234567890')) from...
    【解决方案2】:

    稍作改进就是使用:

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

    当您 to_char 为指数或不同的分组字符或小数分隔符插入“E”时,它仍然可以工作。

    【讨论】:

      【解决方案3】:

      使用此脚本为您的数据生成适当的转换。我写这篇文章是为了帮助通过 Kafka-Connect 将 Oracle 中具有未指定精度和规模的 NUMBER 数据移动到 Postgres。 Kafka-Connect 允许一个选择数据通过查询复制到另一个数据库,但由于我们没有在 Oracle 端设置数字精度,Kafka-Connect 将所有内容作为一个大小数插入 Postgres。即,Oracle 1 将插入为 1.000000000。

      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);
      

      产生以下 dbms 输出:

      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))
      

      【讨论】:

        猜你喜欢
        • 2016-09-28
        • 1970-01-01
        • 2013-08-09
        • 2023-01-18
        • 2021-03-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多