检测 Oracle 数字数据类型的实际精度和小数位数

问题描述 投票:0回答:3

我们的 Oracle 数据源之一拥有数百个表,其中所有数字列都使用 NUMBER 数据类型定义,没有精度和小数位数。但事实上,列可以存储纯整数值或小数值 - 无法仅通过查看数据类型来判断。现在,这是一个大问题,因为当我尝试将任何这些数据加载到大数据工具(Sqoop、Hive、Spark 等)时,所有这些工具都将这些列视为字符串,这是一个处理起来非常痛苦的问题。我认为这是所有基于 JDBC/Java 的工具的问题。

是否可以以某种方式检测存储在 NUMBER 类型列中的值的实际精度和小数位数。我希望 Oracle 将其保留在元数据表中的某个位置,但我在任何地方都没有看到它。我的最后一招是对表中的数据进行随机采样,并在一侧存储转换模式,但我希望有更好的方法。我真的很喜欢

例如,表

TEST
有三列:
ID
AMOUNT
QUANTITY
,全部声明为 NUMBER,未指定精度或小数位数。

但事实上

ID
应该是bigint,
AMOUNT
应该是decimal(18,6),
QUANTITY
应该是int。

create table test (
ID number,
AMOUNT number,
QTY number
)

ID     AMOUNT    QTY
1      200.56    4
2      23.754    5

我不可能手动进行映射,因为我有 600 个表,每个表有 50-300 列。数据采样是我最后的手段。

java oracle jdbc numbers
3个回答
0
投票

一种选择是查询存在的值。

请务必将下面示例中的

{{.THE_COLUMN}}
{{.THE_TABLE}}
替换为您的列和表名称。根据您用于提交查询的环境,您可能需要附加一行由单斜杠 (
/
) 组成的行。

请注意,如果列中没有非空数据,

NUMBER_PRECISION
NUMBER_SCALE
将为空。否则,请注意它们可能会超出目标平台的数字限制。

with
    function WHOLE_DIGITS( NBR number, SEP varchar2 )
        return number
    is
        STR varchar2(40) := to_char( abs( NBR ) );
        POS number := instr( STR, SEP );
    begin
        if POS = 0 then
            return length( STR );
        end if;
        return POS - 1;
    end WHOLE_DIGITS;
    function FRACT_DIGITS( NBR number, SEP varchar2 )
        return number
    is
        STR varchar2(40) := to_char( NBR );
        POS number := instr( STR, SEP );
    begin
        if POS = 0 then
            return 0;
        end if;
        return length( STR ) - POS;
    end FRACT_DIGITS;
select rr.MAX_WHOLE_DIGITS + rr.MAX_FRACT_DIGITS
    as NUMBER_PRECISION
     , rr.MAX_FRACT_DIGITS
    as NUMBER_SCALE
  from (
         select max( WHOLE_DIGITS( ss.NBR, nn.SEP ) )
             as MAX_WHOLE_DIGITS
              , max( FRACT_DIGITS( ss.NBR, nn.SEP ) )
             as MAX_FRACT_DIGITS
           from (
                  select tt.{{.THE_COLUMN}}
                      as NBR
                    from {{.THE_TABLE}}
                         tt
                )
                ss
          cross
           join (
                  select substr( tt.VALUE, 1, 1 )
                      as SEP
                    from NLS_SESSION_PARAMETERS
                         tt
                   where tt.PARAMETER = 'NLS_NUMERIC_CHARACTERS'
                )
                nn
          where ss.NBR is not null
       )
       rr

-2
投票

Oracle 数字类型默认为 38.0


-3
投票

要获取创建时定义到

SCALE
列的
PRECISION
NUMBER
,您可以查询 Oracle 的数据字典视图
ALL_TAB_COLUMNS
,或者
USER_TAB_COLUMNS
(如果所有表都在同一架构下)。

这些视图将信息保存在

DATA_PRECISION
DATA_SCALE
列中。

© www.soinside.com 2019 - 2024. All rights reserved.