暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 如何从数字数据类型列中推断出合适的精度和比例而没有精度和比例

askTom 2017-12-14
278

问题描述

我们的Oracle数据源之一具有数百个表,其中所有数字列均使用数字数据类型定义,而没有精度和比例。但实际上,列可以存储纯整数值或十进制值-无法仅通过查看数据类型来判断这一点。现在,这是一个大问题,因为当我尝试将任何这些数据加载到大数据工具 (sqoop,hive,spark等) 时,所有这些工具都将这些列视为字符串,这是一个非常痛苦的问题。我认为这是所有基于jdbc/java的工具的问题。

我的问题是有可能以某种方式检测存储在具有数字类型的列中的值的实际精度和比例。我希望Oracle将其保留在元数据表中的某个位置,但我在任何地方都看不到。我的最后手段是做一个随机抽样的数据在一个表和存储转换模式在一边,但我希望有一个更好的方法。我真的

示例: tableA列ID具有类型编号,列金额类型编号和列数量类型编号-未指定精度或比例。

但实际上ID应该是bigint,金额应该是十进制 (18,6),数量应该是int。

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

谢谢!

专家解答

我迷路了。没有数据采样,您如何期望了解定义为数字的列,而不是包含 * 任何 * 种数字?除了数字数据类型的限制

https://docs.oracle.com/database/121/SQLRF/sql_elements001.htm#CHDHDHGB

不看数据,我们什么也看不到。你可以做这样的事情:

SQL> create table t ( x number );

Table created.

SQL>
SQL> insert into t values (123);

1 row created.

SQL> insert into t values (123123);

1 row created.

SQL> insert into t values (123.123);

1 row created.

SQL> insert into t values (123.123123123);

1 row created.

SQL> insert into t values (123.123123123123123);

1 row created.

SQL> insert into t values (-12.12312312);

1 row created.

SQL> insert into t values (12.123123123456345643745867);

1 row created.

SQL> insert into t values (12312312313123);

1 row created.

SQL> insert into t values (0.678);

1 row created.

SQL> insert into t values (0.678765675678);

1 row created.

SQL> insert into t values (0.1);

1 row created.

SQL>
SQL> select
  2    length(to_char(trunc(max(abs(x))))) digits,
  3    max(length(to_char(abs(x-trunc(x)))))-1 decimals
  4  from t;

    DIGITS   DECIMALS
---------- ----------
        14         24

1 row selected.


为了得到一个合理的近似值,这很容易制作成动态的东西,例如

SQL> set serverout on
SQL> declare
  2    l_template varchar2(1000) := 'select length(to_char(trunc(max(abs(@@COL))))) digits, max(length(to_char(abs(@@COL-trunc(@@COL)))))-1 decimals from @@TAB';
  3    l_sql varchar2(1000);
  4    l_dig int;
  5    l_dec int;
  6  begin
  7    for i in ( select owner, table_name, column_name
  8               from dba_tab_cols
  9               where data_type in ('NUMBER','FLOAT')
 10               and   owner = 'SCOTT'
 11             )
 12    loop
 13      l_sql := replace(replace(l_template,'@@COL',i.column_name),'@@TAB',i.owner||'.'||i.table_name);
 14      execute immediate l_sql into l_dig, l_dec;
 15      dbms_output.put_line(i.owner||'.'||i.table_name||'.'||i.column_name||'='||l_dig||','||l_dec);
 16    end loop;
 17  end;
 18  /
SCOTT.EMP.EMPNO=4,0
SCOTT.EMP.MGR=4,0
SCOTT.EMP.SAL=4,0
SCOTT.EMP.COMM=4,0
SCOTT.EMP.DEPTNO=2,0
SCOTT.BONUS.SAL=,
SCOTT.BONUS.COMM=,
SCOTT.DEPT.DEPTNO=2,0


轻松调整数据等的任一子集。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论