首页 > 解决方案 > 带有“NULL”列的数字溢出 (0,3)

问题描述

我有一个表(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”列中看到这对于函数 sum 应该没有问题。

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

Typ=2 Len=2: 0,3

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

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

导出数据只导出了第一行的一部分,并在第一次出现这个 0,3 后停止。

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

表是作为选择创建的。现在它被截断并重新填充,NULL 行是 NULL 并且总结工作。

那个专栏的内容是什么?为什么 SQL-Developer 显示 NULL 而不是错误?

标签: sqloracleoracle-sqldeveloper

解决方案


列值不为空,它已损坏。用于数字的内部表示在文档或其他各种类似的地方进行了描述。

第一个字节是指数,它可以 - 只是 - 为零,但不能只有 3 跟随它。我认为你能得到的最接近的是0,3,102-9.8*x10^125

从文档

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 驱动程序可能只是默默地吞下了无法从内部表示进行转换的问题。


推荐阅读