在 Oracle 19c 中按分数/值范围增加 for 循环

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

我们如何在存储过程的 for 循环中将值增加 .25 而不是默认值 1 - oracle 19c?

另外,是否可以使用数字数组作为循环值?如果没有,请指教如何实现。

例如,

fctr1 - 传递 -4 作为 fct 并且 fctr1 需要递增 .25 直到 4

fctr2 - 非周期值范围如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;
/

只需在 FOR 循环中将限制乘以 4,然后在输出中除以 4:

CREATE OR REPLACE procedure sp_test
   ( fct in number )
is
BEGIN
  for fctr1 in (fct*4) .. (4*4) loop
    dbms_output.put_line(fctr1/4);
    dbms_output.put_line(5);
    dbms_output.put_line(7);
    dbms_output.put_line(10);
    dbms_output.put_line(14);
    dbms_output.put_line(15);
    dbms_output.put_line(21);
  end loop;
END;
/

db<>fiddle here

如果您使用的是 21c 之前的版本,则无法在 for 中指定增量值。但是您可以用 WHILE 语句替换它,您可以(实际上必须)进行自己的递增;使用您想要的任何期望值。
至于非周期性值,您退后一步 - 到架构级别。创建一个集合作为 'table of integers',用值填充该集合,将 collection/array 作为另一个参数传递。类似于:

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;  

由于您有一个数字集合,您甚至可以传递传统 for 循环(开始、停止、递增)的 3 个值

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; 

examples here