for循环中的Oracle11g数字溢出

时间:2011-02-18 17:23:04

标签: sql oracle plsql oracle11g ora-01426

我在pl / sql函数中有一个for循环,如:

FOR i IN min..max LOOP

变量i,min,max声明为NUMERIC

在我的情况下,min和max非常大,但范围本身很小,即:

min = 3232236033
max = 3232236286

因为你看到范围约为256,但是有了这个值,oracle会抛出一个数字溢出错误而且我仍然坚持如何让它工作。

我应该如何迭代这些值?

修改

好的,我有一个工作的答案,使用max / min diff的循环,但是它真的不可能在oracle中循环大值吗?

编辑我检索的错误是:

SQL Error: ORA-01426: nadmiar numeryczny
ORA-06512: przy "PS.DHCP", linia 88
01426. 00000 -  "numeric overflow"
*Cause:    Evaluation of an value expression causes an overflow/underflow.
*Action:   Reduce the operands.

第88行代码是:

FOR client_ip IN min_host..max_host

min_host,max_host,client_ip是inet_aton(IP的数字表示)的结果

2 个答案:

答案 0 :(得分:6)

似乎问题来自于我被编译为太小的数字(这似乎是pl / sql的错误), 你可以改变你的循环类型:

while循环正常

set serveroutput on
/
declare
 min_val number;
 max_val number ;
 iterator number ;
begin
    min_val := 3232236033 ;
    max_val := 3232236286 ;

    iterator := min_val;
    while iterator<=max_val loop
        dbms_output.put_line(iterator);
        iterator  := iterator  + 1;
    end loop ;

end;
/

从这里: http://download.oracle.com/docs/cd/E11882_01/appdev.112/e17126/controlstatements.htm#BABEFFDC

  

FOR LOOP Index

     

FOR LOOP语句的索引是   隐式声明为变量   输入本地的INTEGER   环。循环中的语句可以   读取索引的值,但是   无法改变它。外面的陈述   循环不能引用索引。   FOR LOOP语句运行后,   index未定义。 (循环索引是   有时称为循环计数器。)

     

在例4-17中,FOR LOOP   语句尝试更改的值   它的索引,导致错误。

以后: http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28370/loop_statement.htm

  

INDEX_NAME

     

未命名的标识符   循环索引(有时称为   循环计数器)。它的范围是循环   本身;你不能引用索引   在循环之外。

     

index_name的隐式声明   覆盖任何其他声明   在循环之外。引用另一个   具有相同名称的变量,使用a   标签。参见例4-22,“参考   与循环同名的全局变量   计数器”。

     

在循环内部,处理索引   像一个常数:它可以出现在   表达式,但不能分配   值。

因此,即使你在声明中声明了“索引”,它也不会在循环中使用,而是使用隐式创建的INDEX(它的精度似乎太小,无法满足您的需求)

答案 1 :(得分:2)

您可以将循环变量从0运行到minmax之间的差异。这是一个仅将数字写入DBMS_OUTPUT的示例:

DECLARE
  v_min     INTEGER := 3232236033;
  v_max     INTEGER := 3232236286;
  v_diff    PLS_INTEGER;
BEGIN
  v_diff := v_max - v_min;
  FOR i IN 0..v_diff
  LOOP
    -- Use v_min + i where you would have used i.
    dbms_output.put_line(v_min + i);
  END LOOP;
END;
/

编辑:遗憾的是,你不能使用范围运算符来迭代大数。范围运算符..限制在+/- 2 31 范围内。来自PL/SQL documentation

  

在内部,PL / SQL将边界的值分配给临时PLS_INTEGER变量,并在必要时将值舍入为最接近的整数。 PLS_INTEGER的幅度范围是-2 ** 31 .. 2 ** 31。如果绑定计算到该范围之外的数字,则PL / SQL尝试分配时会出现数字溢出错误。