【问题标题】:Oracle Number type without precision - how do I know if it is a whole number or not没有精度的 Oracle Number 类型 - 我如何知道它是否是整数
【发布时间】:2019-06-17 11:49:23
【问题描述】:

我们供应商的数据库包含所有数字的数字类型,包括整数和小数。从字面上看,每个数字类型列都创建为没有精度和比例的 NUMBER。

这是一个大问题,因为我们需要将这些列映射到目标系统上的适当数据类型,我们正在将这些表中的数据加载到其中。

我们需要知道一个数字是整数还是小数。

除了进行随机抽样/数据分析之外,是否可以推断出正确的数据类型?

更新: 我接受了下面的答案和@Bohemian 的建议。除此之外,我将使用 SAMPLE 子句对表进行随机抽样,因为我的源表很大(数十亿行)。

SELECT
    MAX(CASE WHEN col1 IS NOT NULL AND col1 <> round(col1, 0) then 1 else 0 end) as col1,
    MAX(CASE WHEN col2 IS NOT NULL AND col2 <> round(col2, 0) then 1 else 0 end) as col2
FROM TABLE
SAMPLE(0.05)

如果我只想对 X 行进行采样,请使用以下公式对 SAMPLE(N):

Xrows*100/table_rows_total

【问题讨论】:

标签: oracle oracle11g


【解决方案1】:

您可以尝试选择每个 FIELD,并查看 FIELD 的所有值是否都等于 ROUND(FIELD, 0)。如果是,那么该字段应该是整数。如果不是,十进制。

【讨论】:

  • 谢谢,这是个好主意!但这类似于进行数据分析或采样。想知道是否有元数据或统计数据可以用来代替硬拉
  • 如果您将他们的数据库加载到您自己的数据库中,那么您应该只需要“硬拉”一次“测试”,这不是(不应该?)问题。一旦你有了字段的定义,你就不需要再次“弄清楚”了,对吗?或者,如果您担心在“第一次检查”后数据类型可能会发生变化,那么无论您用来提取数据的任何应用程序都可以包含一个函数来检查每个被抓取的值,以确保它“符合”您定义的内容该字段与您这边一样,如果不是,则抛出异常。
  • select sum(case when FIELD1 = round(FIELD1, 0) then 0 else 1 end) as FIELD1_NOT_INT_COUNT, (same for other fields) from mytable。如果您得到零,则该列始终为 int。
  • 我认为这可能是最好的方法,但我会保留这个问题几天,看看是否有更好的方法。
  • 我花了几个小时研究后接受了答案。看起来这是最好的(不幸的是)选择。我希望 Oracle 对数据类型更加严格。
【解决方案2】:

我已经回答了 in this other post 并且您将用于查找所有数字列中的最大小数位数的查询与该查询相同。

要识别具有最大小数位数的列,您可以在将 MY_SCHEMA、MY_TABLE 和数字 10 替换为 25 后运行下面的 SQL 来识别具有超过 25 个小数位的值的列。此 SQL 将生成一个 SQL,应运行该 SQL 以获得您的结果。

SELECT 'SELECT ' || LISTAGG('MAX(LENGTH(TO_CHAR(ABS(' || column_name || ') - FLOOR(ABS(' || column_name || '))))) - 1  AS decimals_' || column_name || CHR(13)
                    , CHR(9)|| ', ') WITHIN GROUP (ORDER BY rn)  ||
                    ' FROM ' || owner || '.' || table_name  || CHR(13) ||
                    ' WHERE '  || CHR(13) ||
                      LISTAGG('(LENGTH(TO_CHAR(ABS(' || column_name || ') - FLOOR(ABS(' || column_name || ')))) - 1) > 10 ' || CHR(13)
                                , CHR(9)|| '  OR  ')
WITHIN GROUP (ORDER BY rn) AS Nasty_Numbers_Finder_Query
FROM
(
    SELECT  owner, table_name, column_name,
        row_number() OVER ( PARTITION BY table_name  ORDER BY rownum) rn
    FROM  dba_tab_columns
    WHERE
        OWNER = 'MY_SCHEMA'
        AND table_name = 'MY_TABLE'
        AND (data_type LIKE '%FLOAT%'
            OR data_type LIKE '%NUMERIC%')
) a
GROUP BY owner, table_name

如需更多信息,我已在博客here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-26
    • 1970-01-01
    • 1970-01-01
    • 2021-04-28
    • 2012-10-29
    • 1970-01-01
    相关资源
    最近更新 更多