存储过程 游标使用实例

本文详细介绍了在Oracle数据库中如何使用游标进行记录集的循环处理。包括游标的声明、打开、读取、处理和关闭等步骤,并通过具体示例展示了不同循环结构的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  使用游标对记录集循环进行处理的时候一般操作如以下几个步骤: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

在Oracle存储过程中,游标(Cursor)是一种用于处理查询结果集的机制。它允许程序逐遍历查询结果,并对每一数据进操作。游标使用通常包括声明、打开、读取和关闭几个步骤。 ### 游标的类型 Oracle中的游标分为两种主要类型: - **显式游标**:由用户定义并管理生命周期(如打开、获取、关闭)。适用于需要更精细控制的情况。 - **隐式游标**:由PL/SQL自动创建和管理,通常用于执DML语句(INSERT, UPDATE, DELETE)以及单SELECT INTO语句。隐式游标的属性可以通过SQL%FOUND, SQL%NOTFOUND, SQL%ROWCOUNT等来访问[^3]。 ### 显式游标使用格式 #### 1. 声明游标 在声明部分定义游标及其关联的SELECT语句。例如: ```sql CURSOR cur IS SELECT * FROM t1; ``` 这里`cur`是游标的名称,后面跟着的是一个SELECT语句,该语句决定了游标将要处理的数据集[^2]。 #### 2. 打开游标 使用`OPEN`语句初始化游标并执相关的SELECT语句,准备数据供后续处理。 ```sql OPEN cur; ``` #### 3. 获取数据 使用`FETCH`语句从游标中取出一数据。这一步通常在一个循环内完成,以便处理所有。 ```sql LOOP FETCH cur INTO variable_list; -- variable_list应该与游标选择列表中的列相匹配 EXIT WHEN cur%NOTFOUND; -- 当没有更多记录时退出循环 -- 在这里可以添加处理每条记录的代码 END LOOP; ``` #### 4. 关闭游标 当不再需要游标时,使用`CLOSE`释放资源。 ```sql CLOSE cur; ``` ### 使用FOR循环简化游标操作 对于显式游标,还可以利用FOR循环简化游标的操作流程,因为在这种情况下不需要显式地打开或关闭游标。例如,在给定的例子中,我们有一个存储过程,它遍历表`t1`的所有记录并将它们输出到控制台: ```sql CREATE OR REPLACE PROCEDURE proc_m_select5_for1_loop IS CURSOR cur IS SELECT * FROM t1; BEGIN FOR t_user IN cur LOOP DBMS_OUTPUT.PUT_LINE('游标row=' || cur%ROWCOUNT || ',员工编号=' || t_user.id || ',员工姓名=' || t_user.sname); END LOOP; END; ``` 在这个例子中,FOR循环自动处理了游标的打开、获取和关闭过程。变量`t_user`是一个记录类型的变量,它的结构与游标`cur`所选择的列相对应。通过这种方式,我们可以轻松地迭代整个结果集并对每个记录执特定的操作[^2]。 ### 返回游标 有时候可能希望存储过程返回一个游标作为输出参数,这样调用者可以直接访问查询结果。为此,可以使用`SYS_REFCURSOR`类型。下面是一个示例存储过程,它根据提供的用户名前缀返回匹配的用户记录: ```sql CREATE OR REPLACE PROCEDURE getDBUSERCursor( p_username IN DBUSER.USERNAME%TYPE, c_dbuser OUT SYS_REFCURSOR) IS BEGIN OPEN c_dbuser FOR SELECT * FROM DBUSER WHERE USERNAME LIKE p_username || '%'; END; / ``` 此存储过程接受一个输入参数`p_username`和一个输出参数`c_dbuser`,后者是一个`SYS_REFCURSOR`类型的游标。在过程体内,使用`OPEN ... FOR`语法打开游标并指定查询语句,然后传递给输出参数。调用这个存储过程后,调用者就可以使用返回的游标来遍历查询结果集[^5]。 以上就是关于Oracle存储过程游标使用方法及格式的基本介绍。接下来的内容将继续探讨这些概念的应用细节和其他相关技术。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值