一 游标
1 概念:指向结果集上下文区域的指针
2 分类:
2.1 隐式游标 存在于事务提交前。对于隐式游标的属性调用方式:sql%属性名
例如:
sql%found 如果记录成功获取,返回true 否则返回false
sql%notfound 如果记录获取失败。返回true,否则返回false
sql%rowcount 返回从游标中获取的记录数
sql%open 始终返回false(只针对隐式游标)
2.2 显式游标 需要先定义再使用
使用解释
1 定义显示游标
CURSOR 游标名称 IS (查询语句,注意:该查询语句就是sql查询语句,没有into或者bulk collect into关键字)
2 打开显示游标
open 游标名称
3 从显示游标中获取数据记录(通过fetch获取)
4 关闭显示游标
获取方式一:
loop
fetch 游标名称 into 变量(可以是复合变量);--将每条结果集存放到变量中
exit when 游标名称%notfound;--退出循环条件
end loop;
注意:必须手动开启游标和关闭游标
获取方式二 :
针对多行数据(借助bulk collect into)
fetch 游标名称 bulk collect into 变量名(该变量类型一定是针对多行数据的)
注意:必须手动开启游标和关闭游标
获取方式三:
for循环
for 变量名 in 游标名称 loop
--操作数据
end loop;
注意:不需要手动开启和关闭游标
举例说明
1 定义显示游标
CURSOR mycur IS SELECT * FROM myemp WHERE empno = 7369;--将员工编号为7369的信息存放到记录类型的变量里面
my myemp%ROWTYPE; --用于获取游标中的数据
2 打开显示游标
open mycur
3 获取记录
3.1
DECLARE
my myemp%ROWTYPE;
CURSOR mycur IS SELECT * FROM myemp WHERE empno = 7369;
BEGIN
OPEN mycur;
LOOP
FETCH mycur INTO my;
dbms_output.put_line(my.empno||my.ename);
EXIT WHEN mycur%NOTFOUND; --循环退出条件
END LOOP;
CLOSE mycur;
END;
/
3.2 获取方式2(针对多行数据)
DECLARE
my myemp%ROWTYPE;
TYPE myrecord IS TABLE OF my INDEX BY BINARY_INTEGER;
emps myrecord;
CURSOR mycur IS SELECT * FROM myemp WHERE dept = 20;--查询部门号为20的所有员工
BEGIN
OPEN mycur;
LOOP
FETCH mycur BULK COLLECT INTO emps;--将全部数据存放到记录数据变量中
END LOOP;
CLOSE mycur;
END;
/
3.3 多行多列数据读取--注意:不需要手动开启关闭游标
DECLARE
TYPE myrecord IS TABLE OF myemp%ROWTYPE INDEX BY BINARY_INTEGER;
emps myrecord;
CURSOR mycur IS SELECT * FROM myemp WHERE deptno = 20;--查询部门号为20的所有员工
BEGIN
FOR emps IN mycur LOOP
dbms_output.put_line(emps.ename);
END LOOP;
END;
/
显示游标定义方式:可以携带参数,具体用法如下:
DECLARE
CURSOR mycur(eno myemp.empno%TYPE) IS SELECT * FROM myemp WHERE empno = eno;
my myemp%ROWTYPE;
my1 myemp%ROWTYPE;
BEGIN
OPEN mycur(7369);
FETCH mycur INTO my;
dbms_output.put_line(my.ename);
CLOSE mycur;
--通过for循环
FOR my1 IN mycur(7369) LOOP
dbms_output.put_line(my1.ename);
END LOOP;
END;
/
通过游标修改数据
在定义显示游标的时候,在查询语句的末尾加上for update。就可以使用
current of 游标名称对当前行进行操作,
具体用法如下:
DECLARE
emp myemp%ROWTYPE;
CURSOR mycur IS SELECT * FROM myemp FOR UPDATE;
BEGIN
OPEN mycur;
LOOP
FETCH mycur INTO emp;
IF emp.sal < 1000 THEN
UPDATE myemp SET sal = emp.sal + 100 WHERE CURRENT OF mycur;
END IF;
EXIT WHEN mycur%NOTFOUND ;
END LOOP;
CLOSE mycur;
END;
/