游标的使用
游标的概念
为了处理 SQL 语句,ORACLE 必须分配一片叫上下文( context area )的区域来处理所必需的信息,其中包括要处理的行的数目,一个指向语句被分析以后的表示形式的指针以及查询的活动集(active set)。
游标是一个指向上下文的句柄( handle)或指针。通过游标,PL/SQL可以控制上下文区和处理语句时上下文区会发生些什么事情。
游标的四个步骤:
1. 定义游标:就是定义一个游标名,以及与其相对应的SELECT 语句,其一般形式为:
CURSOR cursor_name IS select * from emp;
2.打开游标 OPEN cursor_name
打开游标:就是执行游标所对应的SELECT 语句,将其查询结果放入工作区,并且指针指向工作区的首部,标识游标结果集合。
3.提取数据 FETCH cursor_name INTO {variable_list | record_variable };
提取游标:就是检索结果集合中的数据行,放入指定的输出变量中。
4.关闭游标 CLOSE cursor_name;
关闭游标:当提取和处理完游标结果集合数据后,应及时关闭游标,以释放该游标所占用的系统资源,并使该游标的工作区变成无效,不能再使用FETCH 语句取其中数据。关闭后的游标可以使用OPEN 语句重新打开。
游标的四个属性:
游标的FOR循环
PL/SQL语言提供了游标FOR循环语句,自动执行游标的OPEN、FETCH、CLOSE语句和循环语句的功能;当进入循环时,游标FOR循环语句自动打开游标,并提取第一行游标数据,当程序处理完当前所提取的数据而进入下一次循环时,游标FOR循环语句自动提取下一行数据供程序处理,当提取完结果集合中的所有数据行后结束循环,并自动关闭游标。
--游标的使用
declare
v_name emp.ename%type; --声明变量
v_sal emp.sal%type;
cursor c_cursor is select ename,sal from emp ; -- 1.定义游标
begin
open c_cursor ; --2.打开游标
fetch c_cursor into v_name,v_sal ; --3.提取数据 首先读取一条数据
while c_cursor %found loop
dbms_output.put_line('第'||c_cursor%rowcount ||'次读取数据'); ---游标名%rowcount 已读取行数
dbms_output.put_line(v_name||'的工资是'||v_sal);
fetch c_cursor into v_name,v_sal ; --在读取一条数据
end loop;
close c_cursor; --4. 关闭游标
end;
--参数化游标
declare
v_name emp.ename%type; --声明变量
v_sal emp.sal%type;
cursor c_cursor(p_sal emp.sal%type) --游标名后面跟参数 (参数名 类型)
is select ename,sal from emp where sal>p_sal ; -- 1.定义游标
begin
open c_cursor(1500) ; --2.打开游标
if c_cursor%isopen then --判断游标是否打开
fetch c_cursor into v_name,v_sal ; --3.提取数据 首先读取一条数据
while c_cursor %found loop
dbms_output.put_line('第'||c_cursor%rowcount ||'次读取数据');
dbms_output.put_line(v_name||'的工资是'||v_sal);
fetch c_cursor into v_name,v_sal ; --在读取一条数据
end loop;
close c_cursor; --4. 关闭游标
else
dbms_output.put_line('游标有打开');
end if;
end;
--游标的for循环
DECLARE
CURSOR c_sal IS SELECT empno, ename, sal FROM emp ;
BEGIN
--隐含打开游标
FOR i IN c_sal LOOP --固定格式 for 变量 in 游标名
--隐含执行一个FETCH语句
dbms_output.put_line('第'||c_sal%rowcount ||'次读取数据');
DBMS_OUTPUT.PUT_LINE( i.empno||'---'||i.ename||'---'||i.sal) ;
--隐含监测c_sal%NOTFOUND
END LOOP;
--隐含关闭游标
END;
--游标变量
DECLARE
TYPE emp_job_rec IS RECORD( --记录集 里面可以包含多个变量
Employee_id emp.empno%TYPE,
Employee_name emp.ename%TYPE,
Job_title emp.job%TYPE);
TYPE emp_job_refcur_type IS REF CURSOR RETURN emp_job_rec; --定义游标变量类型
Emp_refcur emp_job_refcur_type ; --定义游标变量
Emp_job emp_job_rec; --定义游标变量
BEGIN
OPEN emp_refcur FOR --打开游标变量
SELECT empno, ename, job FROM emp ORDER BY deptno; --查询需要输出的东西
FETCH emp_refcur INTO emp_job; --将查出的东西给 记录集
--fetch c_cursor into ename;
WHILE emp_refcur%FOUND LOOP
DBMS_OUTPUT.PUT_LINE(emp_job.employee_id||': '||emp_job.employee_name||' is a '||emp_job.job_title);
FETCH emp_refcur INTO emp_job;
END LOOP;
END;