Cursor--游标
游标--cursor['kɜːsə]
概念:
在执行SQL语句时,Oracle服务器将分配一个内存区域,不仅存储这个语句,还存储语句的结果 — 称为游标
隐式游标
DML语句或值返回一行结果的select语句时,Oracle服务器将创建一个隐式游标。
隐式游标是自动的。
显示游标
select返回多行结果时,就必须创建一个显示游标 - bulk collect
必须手工声明、打开和关闭
cursor cursor_name is sql(sql指,sql语句)
1.在进行任何处理前,必须首先打开游标:
---打开显示游标
分配必要内存,执行select子句检索的数据加载到游标中
open cursor_name;
打开游标后,可以将游标中包含的数据赋给变量以进行处理
2.从游标中提取数据:
----使用fetch命令来提取游标中的数据
fetch命令提取数据后将值赋给变量
fetch cursor_name into [v_name1,v_name2,………];
%ROWCOUNT
-----处理的行数(DML执行后影响的行数)
sql%rowcount
cursor_name%rowcount
%FOUND
----- 查找到了行
%NOTFOUND
------ 没查找到行
sql%notfound
------- cursor_name%notfound
%ISOPEN
------ 游标是否打开
3.关闭游标
必须明确关闭
在可执行部分使用close命令
close cursor_name;
实例一:
declare
v_no employee.empno%type;
v_name employee.name%type;
v_sal employee.salary%type;
cursor emp_cursor isselect empno , name , salary
from employee
where empno ='0001';
begin
open emp_cursor;
loop
fetch emp_cursor into v_no,v_name,v_sal;
exitwhen emp_cursor%notfound;
dbms_output.put_line('编号'||v_no||'员工'||v_name||'的工资是'||v_sal);
end loop;
close emp_cursor;
end;
游标for循环
(自动open游标)
For name in cursorName loop
... (处理sql语句)
end loop;
(自动close游标)
实例二:
declare
cursor emps_cursor isselect*from employee order by empno;
v_emp employee%rowtype;
begin
for v_emp in emps_cursor loop
dbms_output.put_line('编号'||v_emp.empno||' 的员工: '||v_emp.name||' 的工资是 : '||v_emp.salary);
end loop;
end;
显式游标中:
cursor_name%rowcount -----游标推进行数
cursor_name%found -----fectch有没有找到找到一行
cursor_name%notfound -----fetch没有找到一行
ps:每fetch一次,游标自动推进一行
%rowtype表示某个表的类型,类似某个表的一行,用来存放表中一行的数据
游标能再次打开
实例三:
declare
cursor em_cursor isselect*from employee order by salary desc;
v_emp employee%rowtype;
begin
open em_cursor;
fetch em_cursor into v_emp;
while em_cursor%rowcount<=5and em_cursor%found loop
dbms_output.put_line(em_cursor%rowcount||''||v_emp.name||':'||v_emp.salary);
fetch em_cursor into v_emp;
end loop;
close em_cursor;
end;
课程作业:
--查询所有学生及其专业信息-显示游标
declare
cursor stuMajors isselect s.stuNo, s.name, s.JavaSEScore, s.score, m.name as majorName
from student s, major m
where s.majorNo = m.majorNo;
--定义变量与查询列一致
v_stuNo student.stuNo%type;
v_name student.name%type;
v_seScore student.javasescore%type;
v_sumscore student.score%type;
v_majorName major.name%type;
--记录
type stumr is record(v_stuNo student.stuNo%type, v_name student.name%type,
v_seScore student.javasescore%type, v_sumscore student.score%type,
v_majorName major.name%type);
stum stumr;
begin
open stuMajors;
-- fetch stuMajors into stum;-- fetch 游标中查询的列应与变量记录中列保持一致
-- dbms_output.put_line(stum.v_name);
-- fetch stumajors into v_stuNo, v_name, v_seScore, v_sumscore, v_majorName;
-- dbms_output.put_line(v_name || v_majorName);
loop
fetch stuMajors into stum;
dbms_output.put_line(stum.v_stuNo ||' '|| stum.v_name ||' '|| stum.v_seScore ||' '||
stum.v_sumScore ||' '|| stum.v_majorName );
-- dbms_output.put_line(stuMajors%rowCount);
exitwhen stuMajors%notFound;
end loop;
close stuMajors;
--游标for循环
end;