没有精度的Oracle数字类型-如何知道它是否为整数

没有精度的Oracle数字类型-如何知道它是否为整数,oracle,oracle11g,Oracle,Oracle11g,我们供应商的数据库具有所有数字的数字类型,包括整数和小数。从字面上看,每个数字类型列都是以数字形式创建的,没有精度和比例 这是一个大问题,因为我们需要将这些列映射到目标系统上适当的数据类型,我们正在将这些表中的数据加载到 我们需要知道一个数字是整数还是小数 除了进行随机采样/数据分析外,是否可以推断出正确的数据类型 更新: 我接受了下面的答案和@Bohemian的建议。除此之外,我还将使用SAMPLE子句对表进行随机抽样,因为我的源表很大(数十亿行) 选择 最大值(当col1不为NULL且col

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

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

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

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

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

选择
最大值(当col1不为NULL且col1为四舍五入(col1,0)时,则为1,否则为0结束)为col1,
最大值(col2不为NULL且col2为四舍五入(col2,0)然后为1,否则为0结束)为col2
从桌子上
样本(0.05)
如果我只想对X行进行采样,请使用以下公式对(N)进行采样:


您可以尝试选择每个字段,并查看字段的所有值是否都等于四舍五入(字段,0)。如果是,则该字段应为整数。如果不是,则为十进制。

您可以尝试选择每个字段,并查看字段的所有值是否都等于四舍五入(字段,0)。如果是,则该字段应为整数。如果没有,则为十进制。

我已经回答了这个问题,用于查找所有数字列中最大小数位数的查询与该查询相同

要用最大小数位数标识列,可以在将MY_模式、MY_表和数字10替换为say 25后运行下面的SQL,以标识值超过25位小数的列。此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
有关更多信息,我已经在博客上发表了相关信息。

我已经回答了这个问题,用于查找所有数字列的最大小数位数的查询与该查询相同

要用最大小数位数标识列,可以在将MY_模式、MY_表和数字10替换为say 25后运行下面的SQL,以标识值超过25位小数的列。此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

有关更多信息,我已在博客上发布。

谢谢,这是一个聪明的主意!但这类似于进行数据分析或采样。不知道是否有元数据或统计数据可以用来代替硬拉如果您正在将它们的数据库加载到自己的数据库中,那么您应该只需要“硬拉”一次“测试”,这不是(不应该?)问题。一旦你有了这些字段的定义,你就不需要再“弄清楚”了,是吗?或者,如果您担心数据类型在“首次检查”后可能会发生变化,那么无论您使用什么应用程序来提取数据,都可以包含一个函数,在抓取数据时检查每个值,以确保它“符合”您定义的字段,如果不符合,则抛出异常。
select sum(当FIELD1=round(FIELD1,0)时为case)然后0(否则1结束)作为mytable中的字段1\u NOT\u INT\u COUNT(其他字段相同)
。如果得到零,则列始终为int。我认为这可能是最好的方法,但我会将问题保留几天,看看是否有更好的方法。我花了几个小时研究后接受了答案。看来这是最好的(不幸的)选择。我希望Oracle对数据类型更严格一些。谢谢,这是一个聪明的主意!但这类似于进行数据分析或采样。不知道是否有元数据或统计数据可以用来代替硬拉如果您正在将它们的数据库加载到自己的数据库中,那么您应该只需要“硬拉”一次“测试”,这不是(不应该?)问题。一旦你有了这些字段的定义,你就不需要再“弄清楚”了,是吗?或者,如果您担心数据类型在“首次检查”后可能会发生变化,那么无论您使用什么应用程序来提取数据,都可以包含一个函数,在抓取数据时检查每个值,以确保它“符合”您定义的字段,如果不符合,则抛出异常。
select sum(当FIELD1=round(FIELD1,0)时为case)然后0(否则1结束)作为mytable中的字段1\u NOT\u INT\u COUNT(其他字段相同)
。如果得到零,则列始终为int。我认为这可能是最好的方法,但我会将问题保留几天,看看是否有更好的方法。我花了几个小时研究后接受了答案。看来这是最好的(不幸的)选择。我希望Oracle对数据类型的要求更严格。这里有相关的讨论。在本案例中,JOOQ将与BigDecimal进行相关讨论。在这种情况下,JOOQ将被转换为BigDecimal