PLSQL中BULK COLLECT配合LIMIT子句实现分批插入的问题与解决方案
修复BULK COLLECT分批插入遗漏剩余数据的存储过程
我编写了一个用于数据抽取后插入的存储过程,使用BULK COLLECT实现分批处理,预期每次抽取指定数量(例如10000条)数据后插入对应记录,但原有脚本设置LIMIT值后无法完成全量数据插入:例如总共有6条记录、设置LIMIT为4时,只能插入前4条,剩余2条未被处理,我需要实现先插入4条、再抽取处理剩余2条的分批逻辑。
我已解决该问题,下方附上修复后的完整存储过程脚本,感谢大家提供的建议。
create or replace procedure GPU_DATA_EXTRACTOR_TEST(pid_billdate DATE) is v_cnt NUMBER; c_limit CONSTANT PLS_INTEGER DEFAULT 4; CURSOR c1 IS SELECT DISTINCT intl_prod_id FROM apld_bill_rt abr, acct_bill ab WHERE abr.CHRG_TP = 'INSTALLMENT' AND abr.TAX_CATG_ID = 'NOTAX' AND abr.acct_bill_id = ab.acct_bill_id AND ab.bill_date = pid_billdate; TYPE prod_ids_t IS TABLE OF apld_bill_rt.intl_prod_id%TYPE INDEX BY PLS_INTEGER; l_prod_ids prod_ids_t; begin execute immediate 'truncate table GPU_INV_TEST'; v_cnt := 0; OPEN c1; LOOP FETCH c1 BULK COLLECT INTO l_prod_ids LIMIT c_limit; EXIT WHEN l_prod_ids.COUNT = 0; FOR indx IN 1 .. l_prod_ids.COUNT loop INSERT INTO GPU_INV_TEST SELECT AB.ACCT_BILL_ID, AB.BILL_NO, AB.INV_ID, AB.BILL_DATE, ba2.bill_acct_id, ba1.bill_acct_id parent_bill_acct_id, AB.DUE_DATE, PG.CMPG_ID, ABR.NET_AMT, AB.DUE_AMT, P.PROD_NUM, pds.DST_ID, ABR.DESCR, p.intl_prod_id FROM apld_bill_rt abr, acct_bill ab, prod p, FCBSADM.PROD_DST pds, bill_acct_prod bap, bill_acct ba1, bill_acct ba2, prod_cmpg pg WHERE ab.intl_bill_acct_id = ba1.intl_bill_acct_id AND AB.ACCT_BILL_ID = ABR.ACCT_BILL_ID AND ba1.intl_bill_acct_id = ba2.parent_bill_acct_id AND ba2.intl_bill_acct_id = bap.intl_bill_acct_id AND bap.intl_prod_id = abr.intl_prod_id AND ABR.CHRG_TP = 'INSTALLMENT' AND bap.intl_prod_id = pds.intl_prod_id AND bap.intl_prod_id = p.intl_prod_id AND p.intl_prod_id = pg.intl_prod_id(+) AND ABR.intl_prod_id = l_prod_ids(indx) UNION SELECT AB.ACCT_BILL_ID, AB.BILL_NO, AB.INV_ID, AB.BILL_DATE, ba1.bill_acct_id, ba1.bill_acct_id parent_bill_acct_id, AB.DUE_DATE, PG.CMPG_ID, ABR.NET_AMT, AB.DUE_AMT, P.PROD_NUM, pds.DST_ID, ABR.DESCR, p.intl_prod_id FROM apld_bill_rt abr, acct_bill ab, prod p, FCBSADM.PROD_DST pds, bill_acct_prod bap, bill_acct ba1, prod_cmpg pg WHERE ab.intl_bill_acct_id = ba1.intl_bill_acct_id AND AB.ACCT_BILL_ID = ABR.ACCT_BILL_ID --AND ba1.intl_bill_acct_id = ba2.parent_bill_acct_id AND ba1.intl_bill_acct_id = bap.intl_bill_acct_id AND bap.intl_prod_id = abr.intl_prod_id AND ABR.CHRG_TP = 'INSTALLMENT' AND bap.intl_prod_id = pds.intl_prod_id AND bap.intl_prod_id = p.intl_prod_id AND p.intl_prod_id = pg.intl_prod_id(+) AND ABR.intl_prod_id = l_prod_ids(indx); v_cnt := v_cnt + 1; IF MOD (v_cnt, 4) = 0 THEN COMMIT; END IF; end loop; COMMIT; END LOOP; CLOSE c1; end;
内容的提问来源于stack exchange,提问作者vitaminJava
相关产品推荐
相关产品推荐

