Search code examples
oracle-databasefor-looporacle19cnested-for-loop

Increment for loop by a fraction/ range of values in Oracle 19c


How could we increment value by .25 instead of default 1 in a for loop of a stored procedure - oracle 19c?

Also, is it possible to use an array of numbers as a loop values? If not, please advice how to implement it.

For instance,

fctr1 - passing -4 as fct and fctr1 needs to be incremented by .25 until 4

fctr2 - range of non periodic value such as 5,7,10,14,15,21

CREATE OR REPLACE procedure sp_test
   ( fct in number )
is
BEGIN
    for fctr1 in fct..4 ///increment by .25
         loop
            dbms_output.put_line(fctr1);
            for fctr2 in ///range of non periodic values
            loop
                  dbms_output.put_line(fctr2);
            end loop;
        end loop;
END;
/

Solution

  • If you are using a version prior to 21c you cannot specify an increment value in for. But you can replace it with a WHILE statement where you can (well actually must) do own incrementing; using any desired value your want.
    As far as the non periodic values you step back - to the schema level. Create a collection as a 'table of integers', populate that collection with the values, pass as that collection/array as another parameter. Something like:

    create or replace procedure sp_test
       ( fct     in number 
       , fct2    in non_periodic_values_t
       , by_incr in number default 1
       )  
    is
       l_fct number := 1;
    begin
      while l_fct <= fct
      loop 
         dbms_output.put_line('For l_fct ==> '   ||  l_fct ); 
         
         for fct2_ndx in 1 .. fct2.count
         loop
            dbms_output.put_line('     ' || fct2(fct2_ndx)); 
         end loop;
         l_fct := l_fct + by_incr; 
         
      end loop;
    end;  
    

    Since you have a number collection you can even pass the 3 values of a traditional for loop (start, stop, increment).

    create or replace procedure sp_test2
       ( fct     in number 
       , fct2    in non_periodic_values_t
       , for_val non_periodic_values_t  default  non_periodic_values_t(1,4,1) 
       )  
    is
       l_fct number := for_val(1);
       
    begin
      while l_fct <= for_val(2)
      loop 
         dbms_output.put_line('For l_fct ==> '   ||  l_fct ); 
         
         for fct2_ndx in 1 .. fct2.count
         loop
            dbms_output.put_line('     ' || fct2(fct2_ndx)); 
         end loop;
         l_fct := l_fct + for_val(3); 
         
      end loop;
    end; 
    

    See examples here.