(本文使用的是Oracle19c数据库,scott数据表)
游标在PL/SQL的作用:对于处理查询的多行记录经常使用游标来实现
游标分隐式和显示游标,本文重点描述的是显示游标的用法
显示游标的使用步骤
-- 1.游标的定义:
CURSOR 游标名称 [(参数1 [, 参数2]…)]
[RETURN 返回值类型]
IS
SQL查询语句;
-- 2.打开游标:
OPEN 游标名称 [([参数 =>] 值[, [参数=>] 值]…)];
-- 3.提取游标数据:
FETCH INTO { 变量 };
-- 4.关闭游标:
CLOSE 游标名称;
注意:定义游标不能用 into 关键字
还需要注意的是游标的属性,它可以为游标操作提供判断依据
游标名%FOUND 布尔型属性,当最近一次提取游标操作FETCH成功则为 TRUE,否则为FALSE;
游标名%NOTFOUND 布尔型属性,与%FOUND相反;
游标名%ISOPEN 布尔型属性,当游标已打开时返回 TRUE;
游标名%ROWCOUNT 数字型属性,返回已从游标中读取的记录数。
例:使用游标查询前5名员工姓名和工资
DECLARE-- 定义游标(基于对emp表的查询数据)CURSOR c_cursor IS SELECT ename,sal FROM emp WHERE rownum<6;-- 声明变量用来缓存游标的里面的姓名和工资v_ename emp.ename%TYPE;v_sal emp.sal%TYPE;BEGIN-- 打开游标OPEN c_cursor;-- 提取游标数据(按列的查询顺序,保存在变量里面)FETCH c_cursor INTO v_ename, v_sal;-- 使用while循环遍历游标 (当游标里面还有数据就可以继续循环)WHILE c_cursor%FOUND LOOP-- 每次循环都打印变量的值DBMS_OUTPUT.PUT_LINE('员工名:'||v_ename||',工资:'||v_sal);-- 再提取下一行游标的数据并保存大变量,以便继续打印FETCH c_cursor INTO v_ename, v_sal;END LOOP;-- 关闭游标CLOSE c_cursor;END
带参数的显示游标
格式
-- 定义带参数游标
CURSOR 游标名称(参数1 数据类型, 参数2 数据类型)
IS
SELECT 列 FROM 表
WHERE 条件列1 = 参数1 AND 条件列2 = 参数2;
例:使用带参游标根据部门号查员工记录的详情
DECLARE-- 定义游标带一个number类型的参数,表示可以通过参数传入要查询的部门编号CURSOR c_cursor(dept_no NUMBER) IS-- 游标的查询语句是根据部门号查询出部门的员工姓名SELECT ename FROM emp WHERE deptno = dept_no;-- 声明变量保存员工详情(保存的是整行记录)v_emp emp%ROWTYPE;BEGIN-- 打开游标,传递参数值部门号20OPEN c_cursor(20);-- 使用loop循环(也可以使用while或for循环)LOOP-- 提取游标FETCH c_cursor INTO v_emp;-- 判断游标有没有数据,如果有就打印员工信息,否则输出提示并退出循环IF c_cursor%FOUND THEN-- 此处打印的是员工姓名和工资DBMS_OUTPUT.PUT_LINE('姓名:'||v_emp.ename||',工资:'||v_emp.sal);ELSEDBMS_OUTPUT.PUT_LINE('已经处理完结果集了');-- 退出循环EXIT;END IF;END LOOP;--关闭游标CLOSE c_cursor;END;
使用for循环遍历游标
格式:
FOR 索引变量 IN 游标名称 [(参数值1[, 参数值2]…)] LOOP
-- 游标数据处理代码
END LOOP;
注意:索引变量隐式存在,不需要手动对其显示的声明
例:使用for循环改写 “使用带参游标根据部门号查员工记录的详情”
DECLARE-- 定义游标带一个number类型的参数,表示可以通过参数传入要查询的部门编号 (默认部门号10)CURSOR c_cursor(dept_no NUMBER DEFAULT 10) IS-- 游标的查询语句是根据部门号查询出部门的员工姓名SELECT ename FROM emp WHERE deptno = dept_no;BEGIN-- 使用for循环(注意:此处不用手动打开游标)-- c1是索引变量的名称(自定义的),c_cursor(20)是向游标传入部门号20FOR c1 IN c_cursor(20) LOOP-- 此处打印的是员工姓名和工资DBMS_OUTPUT.PUT_LINE('姓名:'||c1.ename||',工资:'||c1.sal);END LOOP;-- 在for循环后,游标也不需要手动关闭END;
文章转载自全栈精英,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




