游标是构建在PL/SQL中的,主要用来查询数据,获得记录集的指针.一些对数据表的复杂操作我们都可以通过游标来进行。
以下代码是在PLSQL Developer 6.0环境中运行的。为了方便,我们使用 scott/tiget登陆PL/SQL,然后拷贝好样例表:
生成emp_copy表: create table emp_copy as select * from emp;
生成dept_copy表: create table dept_copy as select * from dept;
下面我们可以来进行学习了:
游标分为两种:1 静态游标 2 动态游标
静态游标: 可区分为两种:隐式游标和显示游标
a. 隐式游标是不需要手工来声明、定义和关闭的。
隐式游标有四个属性:%found 如果有影响到数据表的一行和多行,返回TRUE
%notfound 和上面相反,如果没有影响到行,返回TRUE
%rowcount 返回影响的行数
%isopen 如果游标是打开状态,返回false set serveroutput on;
begin
update emp_copy set ename='toms' where empno=7900;
if sql%found then
dbms_output.put_line('表已更新了' || sql%rowcount || '行'); //输出 表已更新了1行
else
dbms_output.put_line('编号没有找到');
end if;
end;
/
b. 显示游标
显示游标需要四个步骤:声明游标->打开游标->获取数据->关闭游标
/**//*使用显示游标查询数据*/
set serveroutput on;
declare
sals emp_copy.sal%type;
cursor mycur is select sal from emp_copy where sal>2000; /**//*申明游标*/
begin
open mycur;
loop
fetch mycur into sals; /**//*提取游标值赋予sals变量*/
exit when mycur%NOTFOUND;//**//*如果最后一条fetch语句没有提取到行数据,则%notfound的值为true*/
dbms_output.put_line(mycur%rowcount || '员工工资: ' || sals);
end loop;
close mycur;/**//*关闭游标*/
commit;
end;
/
/**//*显示游标更新行*/
set serveroutput on;
declare
sals emp_copy.sal%type;
cursor mycur is select sal from emp_copy where sal>2000 for update of sal;
begin
open mycur;
loop
fetch mycur into sals;
exit when mycur%notfound;
update emp_copy set sal=sals*1.1 where current of mycur;/**//*修改游标指向的行*/
end loop;
close mycur;
commit;
end;
/
/**//*带参数的游标*/
set serveroutput on;
declare
dno dept_copy.deptno%type;
eno emp_copy.empno%type;
e_name emp_copy.ename%type;
cursor mysur(dtparam number) is select empno,ename from emp_copy where deptno=dtparam;/**//*定义带参数的游标,注意:游标包含两个字段*/
begin
dno := &部门编号;
open mysur(dno); /**//*打开带参数的游标*/
loop
fetch mysur into eno,e_name;/**//*提取游标值到变量*/
exit when mysur%notfound;
dbms_output.put_line(eno || ' ' || e_name);
end loop;
close mysur;
commit;
end;
/ c 循环游标:可以使用循环游标简化显示游标的代码。循环游标隐式打开游标,自动从活动集获取行,然后在处理完后自动关闭游标
/**//*循环游标:可以简化显示游标的处理代码。循环游标自动从活动集获取行,然后在处理完毕后自动关闭游标*/
set serveroutput on;
declare
cursor mycur is select empno,ename,sal from emp_copy;
begin
for emp_rec in mycur /**//*emp_rec是记录索引*/
loop
dbms_output.put_line('员工编号:' || emp_rec.empno || '员工姓名:' || emp_rec.ename || '员工工资:' || emp_rec.sal);
end loop;
/**//*循环游标在处理完毕后自动关闭*/
end;
/
2. REF游标:动态游标实例
/**//*REF游标: 引用游标,在程序运行时动态决定执行何种查询时,使用REF游标*/
set serveroutput on;
declare
type mycur is ref cursor;/**//*自定义类型mycur,是一个弱类型动态游标类型,因为没有返回参数*/
test_cur mycur; /**//*声明游标变量test_cur*/
t_id number;
t_name varchar2(100);
selection varchar2(1) := upper(substr('&chr',1,1));/**//*取出输入的字符串的第一个字母,并将其变为大写字母。赋给声明的selection变量*/
begin
if selection='E' then
open test_cur for select empno,ename from emp_copy; /**//*关联游标和结果集*/
dbms_output.put_line('员工信息:');
elsif selection='D' then
open test_cur for select deptno,dname from dept;
dbms_output.put_line('部门信息');
else
dbms_output.put_line('请输入正确的信息(E)或(D)');
return;
end if;
fetch test_cur into t_id,t_name; /**//*提取游标值给变量*/
while test_cur%found loop /**//*如果有数据行,则循环*/
dbms_output.put_line('#' || t_id ||':' ||t_name);
fetch test_cur into t_id,t_name;/**//*提取下一条数据行*/
end loop;
close test_cur;
commit;
end;
//**//*REF游标:用REF游标演示动态SQL的使用*/
set serveroutput on;
declare
r_emp emp_copy%rowtype; /**//*定义一个emp_copy表的行类型变量*/
type mycur is ref cursor; /**//*声明一个REF游标类型*/
test_cur mycur; /**//*定义一个mycur游标类型的变量test_cur*/
r_sal number :=2500;
begin
/**//*关联游标到一个结果集,:1是占位符,表示可以引入或导出的第一个参数*/
open test_cur for 'select * from emp_copy where sal>:1 order by sal desc'
using r_sal; /**//*传入参数*/
dbms_output.put_line('工资大于' || r_sal || '的员工有:');
loop
fetch test_cur into r_emp; /**//*将游标中的结果集第一行赋给行对象r_emp*/
exit when test_cur%notfound;
dbms_output.put_line('编号:' || r_emp.empno || '姓名:' || r_emp.ename || '工资:' || r_emp.sal);
end loop;
close test_cur; /**//*记得关闭游标*/
commit;
end;
/
本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/sws8327/archive/2006/11/20/1399932.aspx