数值溢出,带有“ NULL”列(0,3)

时间:2018-07-16 14:35:00

标签: sql oracle oracle-sqldeveloper

我有一个表(Oracle 12.1.0.2.0),当我汇总所得到的值时在其中

ORA-01426: numeric overflow
01426. 00000 -  "numeric overflow"
*Cause:    Evaluation of an value expression causes an overflow/underflow.
*Action:   Reduce the operands.

当我在SQL-Developer中检查值时,我在“ NULL”列中看到了,对于函数求和而言应该没有问题。

当我对此表使用dump(col1)时,结果为

Typ=2 Len=2: 0,3

对于具有NULL的列,这不应该为NULL吗?

还检查“不为空”没有过滤行。

导出数据仅导出第一行的一部分,并在此0,3第一次出现后停止。

SQL Navigator显示“错误”作为此列的值。

表已创建为select。现在,它被截断并重新填充,并且NULL行为NULL,并且进行汇总。

该列的内容是什么?为什么SQL-Developer显示NULL而不是错误?

1 个答案:

答案 0 :(得分:1)

列值不为null,它已损坏。用于数字的内部表示形式是described in the documentation或其他各种位置like this

第一个字节是指数,它可以-只是-为零,但后面不能只有3。我认为您可以获得的最接近的是0,3,102,价格为-9.8 * x10 ^ 125

From the docs

  

NUMBER数据类型存储零以及正和负的固定数字,其绝对值从1.0 x 10 ^ -130到但不包括1.0 x 10 ^ 126。

因此,让我们看看如何存储一些极端:

with t (n) as (
            select  1 * power(10, -130) from dual
  union all select  1 * power(10, 125) from dual
  union all select -1 * power(10, -130) from dual
  union all select -1 * power(10, 125) from dual
  union all select -9.7 * power(10, 125) from dual
  union all select -9.8 * power(10, 125) from dual
  union all select -9.85 * power(10, 125) from dual
  union all select -9.9 * power(10, 125) from dual
)
select n, dump(n) d1, dump(n, 1016) d2 from t

          N D1                             D2
----------- ------------------------------ ------------------------------
 1.000E-130 Typ=2 Len=2: 128,2             Typ=2 Len=2: 80,2
 1.000E+125 Typ=2 Len=2: 255,11            Typ=2 Len=2: ff,b
-1.000E-130 Typ=2 Len=3: 127,100,102       Typ=2 Len=3: 7f,64,66
-1.000E+125 Typ=2 Len=3: 0,91,102          Typ=2 Len=3: 0,5b,66
-9.700E+125 Typ=2 Len=3: 0,4,102           Typ=2 Len=3: 0,4,66
-9.800E+125 Typ=2 Len=3: 0,3,102           Typ=2 Len=3: 0,3,66
-9.850E+125 Typ=2 Len=4: 0,3,51,102        Typ=2 Len=4: 0,3,33,66
-9.900E+125 Typ=2 Len=3: 0,2,102           Typ=2 Len=3: 0,2,66
  

如果您指定的算术表达式的绝对值大于或等于1.0 x 10126,则Oracle返回错误。

select  1 * power(10, 126) from dual;

ORA-01426: numeric overflow

您转储的值0,3的末尾没有102,表示负数,但是如果它是正数,则第一个字节至少为128。

OCI程序错误地处理了一些数字,甚至传统的导入也是如此。不知道数据最初是如何创建的,您可能永远不会确切知道出了什么问题,什么时候出现,或者最初应该是什么值。


奇怪的是,SQL Developer在结果网格中显示null(如果您作为脚本查询,似乎中止了);在SQL * Plus中,即使您set null固定字符串,它也不会显示任何值。 SQL Developer或JDBC驱动程序可能只是默默地吞噬了无法从内部表示形式转换的情况。