Oracle游标

游标

Oracle 游标使用全解 - jack_Meng - 博客园 (cnblogs.com)Oracle学习笔记之显式游标和隐式游标 - 十年半山 - 博客园 (cnblogs.com)

语法

CURSOR cursor_name
[(parameter_name datatype,...)]
IS select_statement;
【语法说明】
CURSOR cursor_name:声明游标,cursor_name是游标的名称。
parameter_name:参数名称。
datatype:参数类型。
select_statement:游标关联的SELECT语句,但该语句不能是SELECT...INTO...语句。

游标属性

%ISOPEN:用于判断游标是否打开,如果已经打开则返回TRUE,如果游标未打开则返回FALSE。%FOUND:此属性可用来检测行数据是否有效。如果有效该属性返回TRUE,否则返回FALSE。%NOTFOUND:与%FOUND属性恰好相反,如果没有提取出数据则返回TRUE,否则返回FALSE。%ROWCOUNT:累计到当前为止使用FETCH提取数据的行数。SQL%ROWCOUNT      整型          代表DML语句成功执行的数据行数  SQL%FOUND       布尔型          值为TRUE代表插入、删除、更新或单行查询操作成功  SQL%NOTFOUND    布尔型          与SQL%FOUND属性返回值相反  SQL%ISOPEN      布尔型          DML执行过程中为真,结束后为假

FOR I IN C9  LOOP  --零用金
	 UPDATE ACCT_D
	 SET ACC_AMT = ACC_AMT + I.QK_AMT,
			 DOR_AMT = DOR_AMT + I.QK_AMT
	 WHERE CORP_NO = VIC_CORPNO
	 AND ACC_SERN = VC_ACC_SERN
	 AND DEPT_NO = I.DEPT_NO
	 AND BRANCH_NO = I.BRANCH_NO
	 AND ITEM_NO = I.ITEM_NO
	 AND YYYYMM = VIC_YM;

	 IF SQL%NOTFOUND THEN
		   INSERT INTO ACCT_D(CORP_NO,ACC_SERN,ITEM_NO,DEPT_NO,BRANCH_NO,YYYYMM,ACC_NO,PAY_TYPE,DC_NO,ACC_AMT,DOR_AMT,RATE,REG_ODR_ID,DOR_ID,DES_2)
		   VALUES (VIC_CORPNO,VC_ACC_SERN,I.ITEM_NO,i.dept_no,I.BRANCH_NO,VIC_YM,I.C_ACCTNO ,'0','C',i.QK_AMT,i.QK_AMT,1,'RMB','RMB',SUBSTR(VIC_YM,1,4)||'年'||substr(VIC_YM,5,2)||'月'||Fun_Get_DeptName(vic_CorpNo,I.DEPT_NO)||'费用');
	 END IF;
END LOOP;

使用一使用LOOP

需要明确游标的打开和关闭,

DECLARE 
CURSOR cfl IS SELECT MONTH,sell FROM sale WHERE sell>10003;
c_row cfl%ROWTYPE;
BEGIN
   OPEN cfl;
   LOOP
   FETCH cfl INTO c_row;
   EXIT WHEN cfl%NOTFOUND; --没有提取出数据
        DBMS_OUTPUT.put_line('month:'||c_row.month||',sell:'||to_char(c_row.sell));
   END LOOP;
    CLOSE cfl;
END;

使用二CURSOR FOR LOOP

这种方式简单很多,省略了open close notfound的操作

DECLARE 
CURSOR cfl IS SELECT * FROM sale WHERE sell>10003;
BEGIN
  FOR curcfl IN cfl LOOP
    DBMS_OUTPUT.put_line('month:'||curcfl.month||',sell:'||to_char(curcfl.sell));
  END LOOP;
END;

带参数的游标

CREATE OR REPLACE PROCEDURE PRO_INCOME_AGE_SCHEDULE AS
--游标一
  CURSOR C1 IS
    SELECT CORP_NO
      FROM CORPORATION
     WHERE CORP_NO NOT IN ('TEST');
--带参数的游标 
  CURSOR ZONENM(VC_CORPNO VARCHAR2) IS
   SELECT * FROM ZONE WHERE CORP_NO = VC_CORPNO AND EXIT_MK='0' order by zone_no;
BEGIN
  --执行日结
  FOR I IN C1 LOOP 
     FOR J IN ZONENM(I.CORP_NO) LOOP  --将参数带入
      --其他操作
     END LOOP;
  END LOOP;
  
END PRO_INCOME_AGE_SCHEDULE;

项目例子

CREATE OR REPLACE PROCEDURE pro_attend_card(VIC_CORPNO VARCHAR2,VIC_YM VARCHAR)
AS
----------定义cursor和变量-------
       CURSOR C0 IS
              SELECT distinct dept_no,branch_no  FROM ATTEND_CARD 
              WHERE CORP_NO = VIC_CORPNO 
              AND  card_ym = VIC_YM;      
      VC_RULNO BRANCH.RUL_NO%TYPE;
      VC_PROJNO BRANCH.PROJ_NO%TYPE;      
BEGIN
----循环cursor start---    
       FOR X IN C0 LOOP
          SELECT rul_no,proj_no into vc_rulno,vc_projno   FROM BRANCH
          WHERE CORP_NO = VIC_CORPNO
          AND DEPT_NO = X.DEPT_NO
          AND BRANCH_NO = X.BRANCH_NO;

          IF vc_rulno IS NULL THEN
               RAISE_APPLICATION_ERROR(-20002,'部门:'|| X.DEPT_NO||'组别:'||X.BRANCH_NO||'没设考勤方案,请找信息中心处理后重算!');
          END IF;
           IF vc_projno IS NULL THEN
               RAISE_APPLICATION_ERROR(-20002,'部门:'||X.DEPT_No||'组别:'||X.BRANCH_NO||'没设薪资方案,请设置后重算!');
          END IF;
       END LOOP;
----循环cursor end---             
END  pro_attend_card;

posted @ 2026-08-30 18:37  清哥的码农生活  阅读(2)  评论(0)    收藏  举报