4

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

FOR i IN min..max LOOP

变量 i, min, max 被声明为NUMERIC

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

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 的数字表示)的结果

4

2 回答 2

7

似乎问题出在我的数字太小(这似乎是 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 索引

FOR LOOP 语句的索引被隐式声明为循环本地的整数类型变量。循环中的语句可以读取索引的值,但不能更改它。循环外的语句不能引用索引。FOR LOOP 语句运行后,索引未定义。(循环索引有时称为循环计数器。)

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

从此:http: //download.oracle.com/docs/cd/B28359_01/appdev.111/b28370/loop_statement.htm

索引名称

一个未声明的标识符,用于命名循环索引(有时称为循环计数器)。它的范围是循环本身;您不能在循环外引用索引。

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

在循环内部,索引被视为常量:它可以出现在表达式中,但不能被赋值。

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

于 2011-02-18T18:02:37.827 回答
3

min您可以将循环变量从 0 运行到和之间的差异max。这是一个仅将数字写入 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 文档

在内部,PL/SQL 将边界值分配给临时 PLS_INTEGER 变量,并在必要时将值四舍五入为最接近的整数。PLS_INTEGER 的幅度范围是 -2**31 .. 2**31。如果边界的计算结果超出了该范围,当 PL/SQL 尝试赋值时,您会得到一个数字溢出错误。

于 2011-02-18T17:35:00.253 回答