存储过程 游标使用实例

  使用游标对记录集循环进行处理的时候一般操作如以下几个步骤:1、把记录集传给游标; 2、打开游标;3、开始循环;4、从游标中取值;5、检查那一行被返回;6、数据处理;7、关闭循环;8、关闭游标。

如下示例:

DECLARE
 CURSOR FirstCursor IS --声明显示游标,并指定结果集
  SELECT T.ACC_NUM ACC_NUM,t.ext_prod_id EXT_PROD_ID, COUNT(1) COUNT,SYSDATE AUDI_TIME
  FROM (SELECT DISTINCT T3.PAY_ACCT_ID,T2.ACCT_ID, T1.ACC_NUM,t1.ext_prod_id
          FROM CRM2_XX.PROD_INST@DB_GROUP_XX     T1,
               CRM2_XX.Serv_Acct_Rel@DB_GROUP_XX T2,
               CRM2_XX.PAYMENT_PLAN@DB_GROUP_XX T3,
               CRM2_XX.COMMON_REGION@DB_GROUP_XX CR
         WHERE T1.REGION_ID = CR.COMMON_REGION_ID
           AND T1.PROD_INST_ID = T2.PROD_INST_ID
     AND T3.SERV_ACCT_REL_ID=T2.SERV_ACCT_REL_ID
           AND T1.STATUS_CD <> '110000'
           AND T2.STATUS_CD = '1') T
 GROUP BY T.ACC_NUM,t.ext_prod_id
HAVING COUNT(1) > 1;
 BEGIN--语法
  FOR REC IN FirstCursor LOOP--开始循环遍历,rec相当java语法中的i,数组的下标
   INSERT INTO NUMCOUNT_MHR_GD_COUSOR
    (acc_num,
    ext_prod_id,
    count,
    audi_time)
   VALUES(
    REC.ACC_NUM,
    REC.EXT_PROD_ID,
    REC.COUNT,
    REC.AUDI_TIME);
   COMMIT;--从游标中取值,并插入目标表
   EXIT WHEN FirstCursor%NOTFOUND;--当游标中再无更多记录时退出
  COMMIT;
 END LOOP;--遍历结束,关闭循环
END;--结束

同下:

create table CS_COUNT_LOG
(
  it          VARCHAR2(30),
  idate       DATE,
  irecore_num NUMBER
)

declare
  iStep  number;
  iCount number;
begin
 
iStep  := 0;
 
iCount := 0;
  for rec in (SELECT T1.*
                FROM CRM2_XX.V_OFFER_INST_INFO T1, AUDI_SAMPLE_JSNJ T2
               where t1.PROD_INST_ID = t2.prod_inst_id) loop
    INSERT INTO ASA_OFFER_INFO_PROV_JSNJ_BK(
      PROV_CODE,
      PROD_INST_ID,
      OFFER_INST_ID,
          OFFER_ID,
          EXT_OFFER_ID,
          OWNER_CUST_ID,
          CHANNEL_ID,
          EFF_DATE,
          EXP_DATE,
          AUDI_DATE,
          AUDI_BATCH
  )
    values
      ('JSNJ',
       rec.PROD_INST_ID,
       rec.OFFER_INST_ID,
       rec.OFFER_ID,
       rec.EXT_OFFER_ID,
       rec.OWNER_CUST_ID,
       rec.CHANNEL_ID,
       rec.EFF_DATE,
       rec.EXP_DATE,
     sysdate,
       '2017-08');
    iStep  := iStep + 1;
    iCount := iCount + 1;
    if iStep = 2000 then
      iStep := 0;
      insert into CS_COUNT_LOG values ('CP',sysdate, iCount);--iStep到2000则置为0,且插入iCount
      commit;
    end if;
  end loop;
  insert into CS_COUNT_LOG values ('CP',sysdate, iCount);--iStep不到2000,则在循环结束后插入iCount
 

end;
/

示例:

CREATE OR REPLACE PROCEDURE sp_sync_plan IS
  CURSOR C_EMP IS --声明显式游标 
    SELECT * FROM dc_check_todo; 
  C_ROW C_EMP%ROWTYPE; --定义游标变量,该变量的类型为基于游标C_EMP的记录 
BEGIN
  --For 循环 
  FOR C_ROW IN C_EMP LOOP 
    DBMS_OUTPUT.PUT_LINE(C_ROW.todo_id || '--' ); 
  END LOOP; 

  --Fetch 循环 
  OPEN C_EMP;--必须要明确的打开和关闭游标 
  LOOP 
    FETCH C_EMP 
      INTO C_ROW; 
    EXIT WHEN C_EMP%NOTFOUND; 
    DBMS_OUTPUT.PUT_LINE(C_ROW.todo_id || '++' ); 
  END LOOP; 
  CLOSE C_EMP; 

  --While 循环 
  OPEN C_EMP;--必须要明确的打开和关闭游标 
    FETCH C_EMP INTO C_ROW; 
    WHILE C_EMP%FOUND LOOP DBMS_OUTPUT.PUT_LINE(C_ROW.todo_id || '**' ); 
      FETCH C_EMP INTO C_ROW; 
    END LOOP; 
  CLOSE C_EMP; 
END sp_sync_plan;

原文地址:https://www.cnblogs.com/emilyyoucan/p/7479227.html