游标:用来处理使用select语句从数据库中检索到的多行记录的工具。
1、游标的分类
1、显示游标 :返回多条记录时,使用显示游标逐行读取
2、隐式游标 :PL/SQL自动为DML语句创建隐式游标,包含一条返回记录
2、显示游标
1、显示游标的使用步骤:
--声明游标
CURSOR cursor_name [(parameter [,parameter]...)]
[RETURN return_type] IS select_statement;
--打开游标
OPEN cursor_name [(parameters)];
--提取游标
FETCH cursor_name INTO variables;
--关闭游标
CLOSE cursor_name;
2、显示游标的属性:
属性名称 | 说 明 |
%found | 用于检验游标是否成功,通常在FETCH语句前使用,当游标按照条件查询出一条记录时,返回true |
%isopen | 判断游标是否处于打开状态,视图打开一个已经打开或者已经关闭的游标,将会出现错误 |
%notfound | 与%found的作用相反,当按照条件无法查询到记录时,返回true |
%rowcount | 循环执行游标读取数据时,返回检索出的记录数据的行数 |
3-1、显示游标--不带参数
DECLARE
CURSOR emp_cursor IS--创建游标
SELECT ename,sal
FROM emp
WHERE empno=7788;
--声明两个变量
v_ename emp.ename%type;
v_sal emp.sal%type;
BEGIN
OPEN emp_cursor;--开启游标
LOOP
FETCH emp_cursor INTO v_ename,v_sal;--读取游标
----判断游标是否为空
EXIT WHEN emp_cursor%NOTFOUND;
dbms_output.put_line('v_ename:'||v_ename || ';v_sal='||v_sal);
END LOOP;
CLOSE emp_cursor;--关闭游标
END;
3-2、显示游标--带参数
DECLARE
CURSOR emp_cursor(no NUMBER) IS--创建游标
SELECT ename
FROM emp
WHERE empno=no;
--声明两个变量
v_ename emp.ename%type;
BEGIN
IF NOT emp_cursor%ISOPEN THEN
OPEN emp_cursor(7788);
END IF;
LOOP
FETCH emp_cursor INTO v_ename;--读取游标
----判断游标是否为空
EXIT WHEN emp_cursor%NOTFOUND;
dbms_output.put_line('v_ename:'||v_ename);
END LOOP;
CLOSE emp_cursor;--关闭游标
END;
3-3、显示游标--循环游标
DECLARE
CURSOR emp_cursor(no NUMBER) IS--创建游标
SELECT ename,sal
FROM emp
WHERE empno=no;
BEGIN
FOR emp_record IN emp_cursor(7788)
LOOP
dbms_output.put_line('v_ename:'|| emp_record.ename);
END LOOP;
END;
4、使用显示游标删除或更新
语法
CURSOR cursor_name IS
select_statement FOR UPDATE [OF columns];
注意:FOR UPDATE [OF columns]为更新查询,锁定选择的行。
(1)单表查询时,可以省略OF 子句。
(2)多表查询时,锁定的行来源于,OF子句后声明的列所在的表中的行,省略OF子句,则都锁。
(OF后的列在哪个表,就锁的是哪个表的行)
例子:假设emp表中有sal字段;dept表中有dname字段。
FOR UPDATE sal 则锁定emp表中的行;
FOR UPDATE dname 则锁定dept表中的行。
示例
DECLARE
CURSOR emp_cursor IS--创建游标
SELECT ename,sal
FROM emp e INNER join dept d
ON e.deptno=d.deptno
FOR UPDATE OF e.sal;
--声明两个变量
v_ename emp.ename%type;
v_sal emp.sal%type;
BEGIN
IF NOT emp_cursor%ISOPEN THEN
OPEN emp_cursor;--开启游标
END IF;
LOOP
FETCH emp_cursor INTO v_ename,v_sal;--读取游标
----判断游标是否为空
EXIT WHEN emp_cursor%NOTFOUND;
UPDATE emp SET sal=v_sal+200 WHERE CURRENT OF emp_cursor;
--UPDATE emp SET ename='bdqn' WHERE CURRENT OF emp_cursor;
END LOOP;
CLOSE emp_cursor;--关闭游标
END;