Переполнение числа в Oracle11g в цикле for - PullRequest
3 голосов
/ 18 февраля 2011

У меня есть цикл for в функции pl / sql, например:

FOR i IN min..max LOOP

переменные i, min, max объявлены как NUMERIC

, в моем случае min и maxчасто очень большой, но сам диапазон маленький, то есть:

min = 3232236033
max = 3232236286

, как вы видите, диапазон составляет около ~ 256, но с этими значениями oracle выдает ошибку переполнения числа, и я застрял, как заставить его работать.

Как мне перебрать эти значения?

РЕДАКТИРОВАТЬ

ОК, у меня есть рабочий ответ, используя цикл max / min diff,но неужели не возможно зациклить большие значения в oracle?

EDIT Ошибка, которую я получаю:

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 ]

6 голосов
/ 18 февраля 2011

кажется, что проблема возникает из-за того, что я был приведен как слишком маленькое число (что, похоже, является ошибкой pl / sql), вы можете изменить тип вашего цикла:

a Хотя цикл работает нормально

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 неявно объявляется как переменная типа INTEGER, локальная дляпетля.Операторы в цикле могут прочитать значение индекса, но не могут его изменить.Заявления вне цикла не могут ссылаться на индекс.После выполнения оператора FOR LOOP индекс не определен.(Индекс цикла иногда называют счетчиком цикла.)

В примере 4-17 оператор FOR LOOP пытается изменить значение своего индекса, вызывая ошибку.

далее к этому: http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28370/loop_statement.htm

index_name

Необъявленный идентификатор, который называет индекс цикла (иногда называемый счетчиком цикла).Его область действия - сама петля;Вы не можете ссылаться на индекс вне цикла.

Неявное объявление index_name переопределяет любое другое объявление вне цикла.Чтобы сослаться на другую переменную с тем же именем, используйте метку.См. Пример 4-22, «Ссылка на глобальную переменную с тем же именем, что и у счетчика цикла».

Внутри цикла индекс обрабатывается как константа: он может появляться в выражениях, но ему не может быть присвоено значение.

Таким образом, даже если вы объявляете «index» в своем объявлении, оно НЕ используется в цикле, а вместо этого использует неявно созданный INDEX (который, кажется, имеет слишком маленькую точность для ваших нужд)

2 голосов
/ 18 февраля 2011

Вы можете запустить переменную цикла от 0 до разницы между min и 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 пытается присвоить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...