Oracle 19c存储过程for循环小数增量及自定义值遍历方案咨询
Oracle 19c 存储过程自定义循环实现方案
调整FOR循环步长为0.25
Oracle 原生的范围式FOR循环FOR i IN a..b仅支持整数类型的起止值,默认步长固定为1,无法直接指定小数步长。
实现方案:通过整数索引循环做数值换算,同时避免浮点数直接比较的精度问题:
- 先计算从起始值
fct到终止值4的总循环次数:total_steps := TRUNC((4 - fct)/0.25) + 1 - 遍历整数索引,将索引换算为对应0.25步长的实际值:
fctr1 := fct + i * 0.25
非周期性离散数值遍历
Oracle 不支持直接在FOR循环的IN子句中写裸数字集合,但可以通过集合类型实现离散值的快速遍历,无需额外定义游标。
实现方案:使用Oracle内置的数字集合类型SYS.ODCINUMBERLIST,直接初始化需要遍历的离散值列表,再通过FOR循环遍历集合元素即可。
完整可运行代码
CREATE OR REPLACE procedure sp_test ( fct in number ) is total_steps number; fctr1 number; -- 定义离散值集合 v_fctr2_list SYS.ODCINUMBERLIST := SYS.ODCINUMBERLIST(5,7,10,14,15,21); BEGIN -- 计算0.25步长对应的总循环次数 total_steps := TRUNC((4 - fct)/0.25) + 1; -- 外层循环:按0.25步长递增 FOR i IN 0..total_steps-1 LOOP fctr1 := fct + i * 0.25; dbms_output.put_line('fctr1: ' || fctr1); -- 内层循环:遍历离散值 FOR j IN 1..v_fctr2_list.COUNT LOOP dbms_output.put_line(' fctr2: ' || v_fctr2_list(j)); END LOOP; END LOOP; END; /
补充说明
- 如果不想用内置的
SYS.ODCINUMBERLIST,也可以自定义嵌套表类型:TYPE num_list IS TABLE OF NUMBER;,用法和内置类型完全一致 - 计算总次数的方式规避了浮点数循环判断的精度误差,不会出现因为浮点精度问题导致多跑/少跑一次循环的问题
内容的提问来源于stack exchange,提问作者Divya
相关产品推荐
相关产品推荐

