Oracle 循环调用存储过程

create or replace procedure p_test_loop
as
--定义一个游标,并将查询结果集赋值给它
CURSOR c1 IS 
select * from tbltest where dept='test'; 

begin
--循环获取游标里的某个字段的值
for cardinfo in c1 loop
     p_testproc(cardinfo.cardid);--使用这个值做一些事情
end loop;
end;

 
### Oracle 循环调用存储过程的实现方法 在 Oracle 数据库中,可以通过游标(Cursor)或者显式的循环结构来实现对存储过程的多次调用。以下是基于引用中的示例代码以及标准实践所提供的解决方案。 #### 方法概述 通过定义一个游标获取目标数据集合,在 `FOR` 或者 `LOOP` 结构中逐一执行存储过程调用操作。这种方法适用于批量处理场景下的动态参数传递需求[^3]。 --- #### 示例代码:使用游标的循环调用 下面是一个完整的例子,展示如何利用游标和循环机制完成多个记录上的存储过程调用: ```sql CREATE OR REPLACE PROCEDURE testdate(v IN NUMBER) IS BEGIN SELECT EN_ID, EN_NAME, ASA_CODE, ASA_NAME, 0 AS_YESTERDAY, v DATEKEEY INTO :output_variable_list -- 假设这里在输出变量列表用于接收结果集 FROM testtable WHERE EN_ID NOT IN ( SELECT EN_ID FROM test2table WHERE datekeey = v ) UNION ALL SELECT EN_ID, EN_NAME, ASA_CODE, ASA_NAME, AS_YESTERDAY, DATEKEEY FROM test2table WHERE datekeey = v; COMMIT; END testdate; CREATE OR REPLACE PROCEDURE testdate2 IS CURSOR datekeey_cursor IS SELECT TO_NUMBER(TO_CHAR(datekeey, 'YYYYMMDD')) AS datekeey_value FROM ( SELECT DATE '2017-01-01' + (ROWNUM - 1) AS datekeey FROM DUAL CONNECT BY ROWNUM <= (DATE '2018-09-18' - DATE '2017-01-01') + 1 ); BEGIN FOR rec IN datekeey_cursor LOOP BEGIN testdate(rec.datekeey_value); EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Error occurred while processing date: ' || rec.datekeek_value); END; END LOOP; COMMIT; EXCEPTION WHEN OTHERS THEN ROLLBACK; RAISE; END testdate2; ``` 此段代码展示了两个部分: 1. **testdate** 存储过程负责单次逻辑运算并接受输入参数; 2. **testdate2** 利用了游标迭代器逐条读取符合条件的数据项,并依次触发子程序运行^。 注意点在于异常捕获环节的设计——即使个别批次失败也不会影响整体流程继续推进下去[^4]. --- #### 示例代码:嵌套循环方式 如果不需要借助游标而更倾向于手动控制索引,则可以采用如下形式: ```sql CREATE OR REPLACE PROCEDURE loop_call_procedure_example IS TYPE proj_id_array_type IS TABLE OF NUMBER INDEX BY PLS_INTEGER; proj_ids proj_id_array_type; customer_id NUMBER; output_message VARCHAR2(100); result_flag VARCHAR2(100); BEGIN /* 获取项目 ID 集合 */ SELECT p.projid BULK COLLECT INTO proj_ids FROM proj_baseinfo p WHERE p.projstage != '-999'; /* 对每个项目分别调用指定存储过程 */ FOR i IN 1..proj_ids.COUNT LOOP BEGIN SELECT p.customerid INTO customer_id FROM proj_baseinfo p WHERE p.projid = proj_ids(i); pro_proj_report_crm_finan(proj_ids(i), customer_id, output_message, result_flag); IF result_flag <> 'SUCCESS' THEN DBMS_OUTPUT.PUT_LINE('Failed on Project ID:' || proj_ids(i)); ELSE DBMS_OUTPUT.PUT_LINE('Success for Project ID:' || proj_ids(i)); END IF; EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('No Customer Found For Project ID:' || proj_ids(i)); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Unexpected Error On Project ID:' || proj_ids(i)); END; END LOOP; COMMIT; EXCEPTION WHEN OTHERS THEN ROLLBACK; RAISE; END loop_call_procedure_example; ``` 这段脚本同样实现了相同功能但采用了数组收集的方式代替传统游标访问模式[^4]. 它允许开发者更加灵活地管理待处理对象及其关联属性. --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值