When you use a for loop, Oracle Database implicitly creates a new variable of type pls_integer. This has precedence over the variable you declared at the start of the block.
You can see this in the following example:
DECLARE
i NUMBER := 5;
BEGIN
FOR i IN 1..3 LOOP
DBMS_OUTPUT.PUT_LINE ('Inside loop, i is ' || TO_CHAR(i));
END LOOP;
DBMS_OUTPUT.PUT_LINE ('Outside loop, i is ' || TO_CHAR(i));
END;
/
Inside loop, i is 1
Inside loop, i is 2
Inside loop, i is 3
Outside loop, i is 5
This implicit variable has a type of pls_integer. Which has an upper limit of 2,147,483,647. Much lower than the numbers in your example!
To overcome this, you can use a basic loop. Increment your variable inside this and write an appropriate exit condition:
create table fromtable (col1 number(17), col2 number(17) );
create table totable (col1 number(17), col2 number(17) );
insert into fromtable ( col1,col2 ) values (17100617100650001, 17100617100650100 );
commit;
declare
i number;
exprec fromtable%rowtype;
cursor c1 is
select *
from fromtable
where col1 = 17100617100650001;
begin
open c1;
loop
fetch c1 into exprec;
exit when c1%notfound;
i := exprec.col1;
loop
insert into totable ( col1 ) values ( i );
i := i + 1;
exit when i > exprec.col2;
end loop;
end loop;
close c1;
end;
/
select * from totable;
COL1 COL2
17100617100650001
17100617100650002
17100617100650003
17100617100650004
17100617100650005
17100617100650006
...
Of course, if all you're doing is loading values from one table to another, why are you using PL/SQL at all?
The following SQL will do the trick:
roll;
insert into totable(col1)
select col1+rownum-1 from fromtable ft,
lateral (select * from dual connect by level <= ft.col2 - ft.col1 + 1);
select * from totable;
COL1 COL2
17100617100650001
17100617100650002
17100617100650003
17100617100650004
17100617100650005
17100617100650006
...