原理:plsql块执行查询和数据操纵dml时,oracle会为其分配上下文区(Contextarea),而游标是指向上下文区的指针,所以操纵游标,就是在操纵指针,应该快不少哈。
目标:
1)使用显示游标及游标属性
2)使用参数游标
3)使用显示游标更新或删除数据
4)使用游标for循环
5)使用游标变量
6)使用fetch * bulk collect into 语句和cursor表达式处理多行多列
个人理解一定要灵活使用,游标与复合表,是操作单条多列还是多列多行,单列多行,然后在去选择对应的表或者游标,开始不熟的时候使用一定要先想,用这个处理行不行,这样能帮助你回忆以前记忆的游标的知识,一一排除及找到肯定的以后,这样熟了以后就快了
个人理解隐含式游标只有那种处理select into和dml的语句是,即单行的数据 这里还是有疑问
显示游标呢处理多行单列或者多列的数据。
【显示游标】
使用显示游标记住几步:定义 、打开、遍历、关闭
declare cursor cursor_name is select_statement;
open cursor_name;
fetch cursor_name into variable1,variable2...
fetch cursor_name bulk collect into collect1,collect2...
close cursor_name;
【游标属性】
显示游标属性用于返回显示游标的执行信息,包括%ISOPEN,%FOUND,%NOTFOUND,%ROWCOUNT,一定要注意与PLSQL异常区分开如NOT_DATA_FOUND ,TOO_MANY_ROWS等
eg:fetch * into 一次只能处理一条语句,为了处理多条需要使用循环
open emp_cursor;
loop
fetch emp_cursor into v_ename,v_sal ;
exit when emp_cursor%NOTFOUND;
dbms_output.put_line(v_ename||v_sal);
end loop;
close emp_cursor;
end;
fetch * bulk collect into提取全部数据
open emp_cursor;
fetch emp_cursor bulk collect into ename_table;
for i in 1..ename_table.count loop
dbms_output.put_line(ename_table(i));
end loop;
end;个人理解这种方式只在处理当列多行方面比较在行
还有一个方法是 fetch * bulk collect into limit rows限制行,就是可以输入多少行。
用游标定义记录变量
cursor emp_cursor is select ename,sal from emp;
emp_record emp_cursor%ROWTYPE:
fetch emp_cursor into emp_record;
dbms_output.put_line(emp_record.sal);
【参数游标】
参数游标顾名思义肯定是游标里边需要一个输入参数,这个参数只能指定数据类型,没有长度,在游标子查询的where字句中引用该参数,否则失去了游标的意义。
declare
cursor emp_cursor(no number) is
select ename,sal from emp where deptno=no;
就是每次输入不同的no值就会得到不同的结果,
【游标更新删除数据此项比较复杂,容易引起问题,后续补充不建议使用】
【游标的for循环】
游标的for循环会隐式的打开游标,提取数据并关闭游标,每循环提取一次数据
for record_name in cursor_name loop
statement1;
statement2;
..
end loop;
declare
CURSOR emp_cursor is select ename,sal from emp;
begin
for emp_record in emp_cursor loop
dbms_output.put_line(emp_cursor%ROWCOUNT||emp_record.ename);
end loop;
end;
简写的
for emp_record in (select ename,sal from emp) loop
dbms_output.put_line(emp_record.ename);
end loop;
显示游标与游标变量的区别,显示游标定义的时候指明select 而游标变量定义是不需要select,可以在打开的时候指定select 也就是open emp_cursor for select_statement;
【游标变量】
为了使用游标变量,必须使用参照类型ref cursor
type ref_type_name is ref cursor [return return_type]
cursor_variable ref_type_name;
cursor_variable就是游标变量名
打开游标
open cursor_variable for select_statement;
提取数据
fetch cursor_variable into variable1,variable2..;
fetch cursor_variable bulk collect into collect1,collect2..
关闭游标
close cursor_variable
eg:定义参照类型的游标变量
declare
type emp_cursor_type ref cursor;
emp_cursor emp_cursor_type;
emp_record emp_cursor%ROWTYPE;
begin
open emp_cursor for select * from emp;
loop
fetch emp_cursor into emp_record;
exit when emp_cursor%NOTFOUND ;
dbms_output.put_line(emp_record.ename);
end loop;
end ;
eg:定义参照类型的时候如果指定了return字句,那么返回的必须与定义的类型匹配,
declare
type emp_record_type is record(
name varchar2(10),salary number(6,2)
);
type emp_cursor_type is ref cursor return emp_cursor_type; 带返回的参照变量
emp_cursor emp_cursor_type;
emp_record emp_record_type;
begin
open emp_cursor for select ename,sal from emp where deptno=20;
loop
fetch emp_cursor into emp_record;
exit when emp_cursor%NOTFOUND;
dbms_output.put_lin(emp_cursor%ROWTYPE||emp_record.name);
end loop;
end;