游标--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;
实例一:
declarev_no employee.empno%type;v_name employee.name%type;v_sal employee.salary%type;cursor emp_cursor isselect empno , name , salaryfrom employeewhere empno ='0001';beginopen emp_cursor;loopfetch 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游标)
实例二:
declarecursor emps_cursor isselect*from employee order by empno;v_emp employee%rowtype;beginfor v_emp in emps_cursor loopdbms_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表示某个表的类型,类似某个表的一行,用来存放表中一行的数据
游标能再次打开
实例三:
declarecursor em_cursor isselect*from employee order by salary desc;v_emp employee%rowtype;beginopen em_cursor;fetch em_cursor into v_emp;while em_cursor%rowcount<=5and em_cursor%found loopdbms_output.put_line(em_cursor%rowcount||''||v_emp.name||':'||v_emp.salary);fetch em_cursor into v_emp;end loop;close em_cursor;end;
课程作业:
--查询所有学生及其专业信息-显示游标declarecursor stuMajors isselect s.stuNo, s.name, s.JavaSEScore, s.score, m.name as majorNamefrom student s, major mwhere 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;beginopen 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);loopfetch 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;