oracle游标的使用

Oracle游标详解
本文详细介绍了Oracle数据库中游标的定义、声明方式及其属性,并通过多个实际案例演示了如何使用游标来查询和处理数据。

1.游标的定义

游标(Cursor),也称之为光标,从字面意思理解就是游动的光标。

游标是映射在结果集中一行数据上的位置实体。

游标是从表中检索出结果集,并从中每次指向一条记录进行交互的机制。


2. 游标的声明

CURSOR 游标名  [ (参数名  数据类型[,参数名 数据类型]...)]

     IS  SELECT   语句;

【示例】

无参游标:

cursor c_emp is select ename from emp;

有参游标:

cursorc_emp(v_deptno emp.deptno%TYPE) is select ename from emp where deptno=v_deptno;

3.游标的属性

游标的属性

返回值类型

说明

%ROWCOUNT

整型

获得FETCH语句返回的数据行数

%FOUND

布尔型

最近的FETCH语句返回一行数据则为真,否则为假

%NOTFOUND

布尔型

%FOUND属性返回值相反

%ISOPEN

布尔型

游标已经打开时值为真,否则为假


4.游标的使用案列

--使用游标查询emp表中所有员工的姓名和工资,并将其依次打印出来。

DECLARE

  --声明一个游标

  CURSOR C_EMP ISSELECT * FROM EMP;

  --记录型变量

  v_emp emp%ROWTYPE;

 

BEGIN

  --打开游标,执行查询

  OPEN C_EMP;

  --使用游标,循环取值

  LOOP 

    --获取游标的值放入变量的时候,必须要into前后要对应(数量和类型)

    FETCH C_EMP INTO v_emp; 

    EXITWHEN C_EMP%NOTFOUND

    --输出打印

    DBMS_OUTPUT.PUT_LINE('员工的姓名:' || v_emp.ename || ',员工的工资' || v_emp.sal); 

  ENDLOOP;

CLOSE c_emp ;--关闭游标,释放资源 

END;

5.SCOTT表使用游标案列,上面有讲解了下面的就不写解释了。


(1)例题:显示30部门的所有员工的编号及姓名,要求格式是  编号--姓名

DECLARE
erow  emp%ROWTYPE;
CURSOR cur_1 IS SELECT * FROM emp WHERE deptno=30;

BEGIN
       OPEN cur_1;
       LOOP
         FETCH cur_1 INTO erow;
         EXIT WHEN cur_1%NOTFOUND;
         dbms_output.put_line(erow.empno||'-----'||erow.ename);
      END LOOP;
      CLOSE cur_1;
END;
(2)例题:显示30部门的所有员工的编号及姓名,要求格式是  编号--姓名(部门编号手动输入)
DECLARE
erow emp%ROWTYPE;
CURSOR cur_2 IS SELECT * FROM emp WHERE deptno=&部门编号;
BEGIN
       OPEN cur_2;
       LOOP
         FETCH cur_2 INTO erow;
         EXIT WHEN cur_2%NOTFOUND;
         dbms_output.put_line(erow.empno||'-----------'||erow.ename);
       END LOOP; 
       CLOSE cur_2;
END;
(3)例题查询10号部门的员工的姓名和薪资

DECLARE
CURSOR  c_1 (v_deptno emp.deptno%TYPE) IS SELECT ename,sal FROM emp WHERE deptno=v_deptno;
v_ename emp.ename%TYPE;
v_sal emp.sal%TYPE;
BEGIN
  OPEN c_1(10);
  LOOP
    FETCH c_1 INTO v_ename,v_sal;
    EXIT WHEN c_1%NOTFOUND;
    dbms_output.put_line(v_ename||'---'||v_sal); 
  END LOOP;  
  CLOSE c_1;
END;
(4)例题查询10号部门的员工的姓名和薪资(部门手动输入)
DECLARE  
CURSOR c_2(v_deptno emp.deptno%TYPE) IS  SELECT ename,sal FROM emp  WHERE deptno = v_deptno;
v_ename emp.ename%TYPE;
v_sal emp.sal%TYPE;
vv_deptno emp.deptno%TYPE;
BEGIN
  vv_deptno :=&部门编号;
  OPEN c_2(vv_deptno);
  LOOP
    FETCH c_2 INTO v_ename,v_sal;
    EXIT WHEN c_2%NOTFOUND;
    dbms_output.put_line(v_ename||'--'||v_sal);
  END LOOP;
  CLOSE c_2;
  
END;



<think>我们正在处理关于Oracle游标使用方法和示例的查询。根据提供的引用,我们可以总结如下: 引用[1]和[2]介绍了游标的两种类型:显式游标和隐式游标。显式游标由程序员显式控制,而隐式游标Oracle自动管理。 引用[2]和[3]提供了显式游标的基本使用示例,包括声明、打开、循环获取数据以及关闭游标。 引用[3]和[4]展示了游标的简便写法,特别是使用FOR循环自动处理游标的打开、获取和关闭。 引用[5]提到在游标声明中可以使用变量绑定。 因此,我们可以按照以下结构回答: 1. 介绍游标的两种类型。 2. 分别给出显式游标和隐式游标(或简便写法)的使用示例。 3. 注意在示例中展示如何在游标使用变量(根据引用[3]和[5])。 同时,根据用户要求,我们需要在回答中自然地添加引用标识,并在最后生成相关问题。 注意:用户要求用中文回答,并且代码块需要正确格式化。 </think>### Oracle游标使用方法和示例 Oracle游标是处理SQL查询结果集的重要工具,主要分为显式游标和隐式游标两种类型: #### 1. 显式游标 由程序员**显式声明并控制**生命周期,包含四个步骤: - **声明游标**:定义游标名称和关联查询 - **打开游标**:执行查询并准备结果集 - **提取数据**:逐行获取结果 - **关闭游标**:释放资源 ```sql DECLARE CURSOR emp_cursor IS SELECT employee_id, first_name, salary FROM employees WHERE department_id = 90; -- 声明游标[^2] v_emp_record emp_cursor%ROWTYPE; -- 定义行类型变量 BEGIN OPEN emp_cursor; -- 打开游标 LOOP FETCH emp_cursor INTO v_emp_record; -- 提取数据 EXIT WHEN emp_cursor%NOTFOUND; -- 退出条件 DBMS_OUTPUT.PUT_LINE( 'ID:' || v_emp_record.employee_id || ' 姓名:' || v_emp_record.first_name || ' 薪资:' || v_emp_record.salary ); END LOOP; CLOSE emp_cursor; -- 关闭游标 END; ``` #### 2. 隐式游标(FOR循环简化版) Oracle**自动管理**游标生命周期,无需显式开关操作: ```sql BEGIN FOR emp_rec IN ( -- 自动声明并打开游标 SELECT ename, job FROM emp WHERE sal > 5000 -- 使用变量示例 ) LOOP DBMS_OUTPUT.PUT_LINE( emp_rec.ename || ' - ' || emp_rec.job ); -- 自动提取并关闭游标[^3][^4] END LOOP; END; ``` #### 3. 嵌套游标应用 支持多层游标嵌套处理主从关系: ```sql DECLARE v_total_sal NUMBER; BEGIN FOR dept_rec IN (SELECT deptno, dname FROM dept) LOOP v_total_sal := 0; FOR emp_rec IN ( -- 嵌套游标 SELECT ename, salary FROM emp WHERE deptno = dept_rec.deptno ) LOOP v_total_sal := v_total_sal + emp_rec.salary; END LOOP; DBMS_OUTPUT.PUT_LINE( dept_rec.dname || ' 部门总薪资: ' || v_total_sal ); -- 部门级统计[^4] END LOOP; END; ``` > **关键优化技巧**: > - 使用`WHERE CURRENT OF`更新当前游标行[^1] > - 批量处理时用`BULK COLLECT`减少上下文切换 > - 显式游标使用后必须关闭防止内存泄漏 > - 优先选择FOR循环简化代码并避免忘记关闭游标[^5]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值