游标
对游标的理解:游标就是临时存储从数据库中提取的数据块,游标的运行机制就是在内存中对数据进行处理,从而大大提高数据处理的效率.
游标的分类:显式游标和隐式游标.
<1>隐式游标
DML操作和单行SELECT语句会使用隐式游标.
隐式游标的属性:
隐式游标的属性 |
返回值类型 |
意义 |
sql%rowcount |
int |
值为DML语句成功执行的行数 |
sql%found |
bool |
值为true时表示DML操作和单行SELECT语句成功执行 |
sql%notfound |
bool |
值为true时表示DML操作和单行SELECT语句未成功执行 |
sql%isopen |
bool |
DML操作在执行过程中为真,结束后为假 |
隐式游标的实例:
set serveroutput on
begin
update emp set sal=sal+100 where empno=1234; --系统自动使用隐式游标
if sql%found then --使用隐式游标的属性
dbms_output.put_line('修改操作成功!');
commit;
else
dbms_output.put_line('修改操作失败!');
end if;
end;
<2>显式游标
显式游标的属性:
显式游标的属性 |
返回值类型 |
意义 |
游标名%rowcount |
int |
获得fetch语句返回的数据行数 |
游标名%found |
bool |
值为true时表示最近的fetch语句返回一行数据 |
游标名%notfound |
bool |
值为true时表示最近的fetch语句未返回一行数据 |
游标名%isopen |
bool |
游标打开时为真,否则为假 |
我用几个带注释的实例来介绍显式游标
实例1
不带参数的游标
查询empno=7788的雇员姓名和工资
set serveroutput on
declare
v_ename emp.ename%type;
v_sal emp.sal%type;
cursor emp_cursor is select ename,sal from emp where empno=7788; --声明游标emp_cursor
begin
open emp_cursor; --打开游标emp_cursor
fetch emp_cursor into v_ename,v_sal; --提取游标emp_cursor中的数据到变量v_ename,v_sal中
dbms_output.put_line(v_ename||'******'||v_sal);
close emp_cursor; --关闭游标emp_cursor
end;
实例2
带参数的游标
查询部门10的雇员姓名
set serveroutput on
declare
v_ename emp.ename%type;
cursor emp_cursor(p_deptno number) is select ename from emp where deptno=p_deptno; --声明带参数p_deptno的游标emp_cursor
begin
open emp_cursor(10); --对于带参数的游标,打开时要通过参数传递具体值
loop
fetch emp_cursor into v_ename; --提取游标emp_cursor的数据到变量v_ename中
exit when emp_cursor%notfound; --使用游标的notfound属性
dbms_output.put_line(v_ename);
end loop;
close emp_cursor; --关闭游标emp_cursor
end;
实例3
游标属性的使用
查询所有雇员的名字和工资
set serveroutput on
declare
v_ename emp.ename%type;
v_sal emp.sal%type;
cursor emp_cursor is select ename,sal from emp; --声明游标emp_cursor
begin
open emp_cursor; --打开游标emp_cursor
if emp_cursor%isopen then --使用游标的isopen属性
dbms_output.put_line('游标是开着的!');
loop
fetch emp_cursor intov_ename,v_sal; --提取游标emp_cursor的数据到变量v_ename,v_sal中
exit when emp_cursor%notfound; --使用游标的notfound属性
dbms_output.put_line(v_ename||'***'||v_sal);
endloop;
else
dbms_output.put_line('游标是关着的!');
end if;
dbms_output.put_line(emp_cursor%rowcount); --使用游标的rowcount属性
close emp_cursor;
end;
实例4
动态游标的使用
查询每个工资段的人
set serveroutput on
declare
type cursor_type is ref cursor; --定义类型为cursor_type的动态游标
a cursor_type; --声明动态游标a
data varchar2(100);
v_ename emp.ename%type;
v_sal1 emp.sal%type:=0; --声明v_sal1和v_sal2来限定工资段,并赋初值
v_sal2 emp.sal%type:=1000;
begin
loop
dbms_output.put_line('工资大于'||v_sal1||'小于等于'||v_sal2||'的有:');
data:='select ename from emp where sal>'||v_sal1|| ' and sal<=' ||v_sal2|| ''; --注意这里将v_sal1和v_sal2转化为值的做法
open a for data; --为data打开动态游标a
loop
fetch a into v_ename; --提取动态游标a中的数据到v_ename
exit when a%notfound;
dbms_output.put_line(v_ename);
end loop;
exit when v_sal2>5000;
v_sal1:=v_sal1+1000;
v_sal2:=v_sal2+1000;
end loop;
end;