检测 Oracle 数字数据类型的实际精度和比例

Posted

技术标签:

【中文标题】检测 Oracle 数字数据类型的实际精度和比例【英文标题】:Detect actual precision and scale for Oracle number data type 【发布时间】:2017-12-14 14:15:12 【问题描述】:

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

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

例如,一个表 TEST 有三列,IDAMOUNTQUANTITY,它们都声明为没有指定精度或小数位数的 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 列。数据采样是我最后的手段。

【问题讨论】:

所以您的问题是您使用的工具将数字视为字符串而不是 int/floats 等?你到底用什么来加载 - there's a type mapping that should be used 肯定不会将数字放入字符串中。 我不明白这个问题。您在 Oracle 中拥有所有 NUMBER。但是在 Hive 中,您想要其中一些 INTEGER、一些 FLOATS、一些 SMALLINT 等?您应该知道您的数据,或者只是在导入之前对其进行采样/分析...... 这里是示例:tableA 列 ID 的类型为 NUMBER,列数量类型为 NUMBER,列数量类型为 NUMBER - 未指定精度或小数位数。但实际上 ID 应该是 bigint,数量应该是小数(18,6),数量应该是 int。我不可能手动进行映射,因为我有 600 个表,每个表有 50-300 列。正如我在问题中提到的,数据采样是我最后的手段 @Ben 我正在使用 sqoop 和 Hive 以及与 NiFi 相同的问题。 Kafka JDBC 连接器的同样问题 - 实际上更糟,因为 Kafka 分配了平面错误的 decimal(38,0) 数据类型。所以我决定将它们作为字符串加载,然后有一个处理步骤来转换/映射到正确的数据类型,但我需要弄清楚如何分配正确的数据类型并从源 Oracle 模式推断它 @FlorinGhita 我希望我能知道 600 个表中的所有数据,每个表有 50-300 列 :) 但我不是那么好 【参考方案1】:

Oracle 数字类型默认为 38.0

【讨论】:

它不是,它将使用它需要使用的任何精度/比例来适应实际数字 - 请参阅此处的示例docs.oracle.com/cd/B28359_01/server.111/b28318/…【参考方案2】:

若要在创建时将SCALEPRECISION 定义为NUMBER 列,您可以查询Oracle 的数据字典视图ALL_TAB_COLUMNSUSER_TAB_COLUMNS(如果所有表都在同一架构下)。

这些视图将信息保存在DATA_PRECISIONDATA_SCALE 列中。

【讨论】:

如果数据库中没有声明精度或比例,这两者都将返回 NULL。这是 OP 的问题。 @Ben,那么你在查询中使用NVL(DATA_PRECISION, 38) as DATA_PRECISION, NVL(DATA_SCALE, 0) as DATA_SCALE。当 DDL 中未定义精度/比例时,这将使用默认值。你能解释一下我的答案是如何不正确的,证明投反对票是合理的吗? OP 明确要求提供包含此信息的元数据表。 OP 要求确定数据是什么的方法,而不是元数据的样子。 OP 很清楚如何获取元数据。 嗯..不,问题指出“我的问题是有可能以某种方式检测存储在 NUMBER 类型列中的值的实际精度和比例。我希望 Oracle 将其保存在元数据表中的某个位置,但是我在任何地方都没有看到。”。哪个 1)没有问“数据是什么”,2)没有表明 OP 知道“如何获取元数据”。如果您认为我的回答不正确,请说明如何。或者更好的是,自己回答问题。 我知道 Oracle 表和列元数据,但正如我在问题中解释的那样,它在这里不起作用,因为精度和比例设置为 null

以上是关于检测 Oracle 数字数据类型的实际精度和比例的主要内容,如果未能解决你的问题,请参考以下文章

如何解释数据库中数字的精度和比例?

具有任意精度和一定比例的数字格式的 Oracle to_char 函数

无法理解 DBMS 中数值数据类型的精度和小数位数

Postgres 中数字数据类型的精度和小数位数是多少?

Oracle Number 数据类型及其严格性

ORACLE 中NUMBER类型默认的精度和Scale问题