游标
一.游标简介
1.游标类似于编程语言中指针的概念.
2.游标的分类
游标的主要类型分别静态游标和动态游标,静态游标是常用的游标.
静态游标又分为显示游标和隐示游标.
二.显示游标和隐式游标
(一)显示游标
1.声明显示游标
(1)声明游标
delcare cursor 游标名称 is 查询语句;
eg. declare cursor cu_emp is
select empno,ename,sal from emp;
(2)声明列变量
<被声明变量> <表名>.<参照列>%type;
eg. declare cursor cu_emp is
select empno,ename,sal from emp;
emp_id emp.empno%type;
emp_name emp.ename%type;
emp_sal emp.sal%type;
(3)声明行变量
变量名 表名%rowtype;
eg. declare cursor cu_emp is
select * from emp;
emph emp%rowtype;
2.使用显示游标
(1)打开游标
open 游标名称;
(2)通过游标来捕获数据
fetch 游标名称 into 变量;
3.游标使用方法
(1)使用普通变量获取游标信息
set serverout on;
declare cursor cu_emp is select empno,ename,sal from emp;
emp_id emp.empno%type;
emp_name emp.ename%type;
emp_sal emp.sal%type;
begin
open cu_emp;
fetch cu_emp into emp_id,emp_name,emp_sal;
while cu_emp%found loop
dbms_output.put_line(emp_id||':'||emp_name||':'||emp_sal);
fetch cu_emp into emp_id,emp_name,emp_sal;
end loop;
end;
/
(2)使用行类型变量来获取油表信息
set serverout on;
declare cursor cu_emp is select * from emp;
emph emp%rowtype;
begin
open cu_emp;
fetch cu_emp into emph;
while cu_emp%found loop
dbms_output.put_line(emph.ename||':'||emph.job||':'||emph.sal);
fetch cu_emp into emph;
end loop;
end;
/
(3)为游标传递参数
显示游标可以带有参数,参数的意义在于为获取记录集合制定搜寻条件
declare cursor cu_emp(minSal in number,maxSal in number) is select * from emp
where sal>=minSal and sal<=maxSal;
emph emp%rowtype;
begin
open cu_emp(2000,3000);
fetch cu_emp into emph;
while cu_emp%found loop
dbms_output.put_line(emph.ename||':'||emph.job||':'||emph.sal);
fetch cu_emp into emph;
end loop;
close cu_emp;
end;
/
4.游标总结
(1)fetch命令可以捕获当前记录,并将指针移至下一条记录.游标位置下移才能获得新纪录,如果使用循环,但是未在循环中加入fetch命令,则游标总会处于首条记录,容易产生死循环.
(2)在游标使用完毕后,应该使用close命令将其关闭,以防占用数据库资源.
5.游标属性
(1)found
当用户执行了fetch命令,oracle将更新游标的found属性,如果利用fetch命令成功捕获了记录,那么found将被置为真(true),否则为假(false)
(2)notfound
该属性是found属性的对立面,当fetch命令不能成功捕获记录时,将返回true,否则返回false
(3)rowcount
该属性每次执行fetch时进行更新,用于返回当前时刻已捕获的记录数
(4)isopen
该属性被open和close命令更新,用于判断游标是否处于打开状态.打开为真(true),否则为假(false)
(二)隐式游标
隐式游标是相对于显式游标而言.
显示游标:用户通过声明游标(declare),打开游标(open),使用游标(fetch),关闭游标(close)等步骤控制显式游标的生命周期.
隐式游标则不允许用户声明和控制,仅限于使用.隐式游标包括两种:使用oracle预定义的名为SQL的隐式游标和使用cursor for loop来进行循环的隐式游标.
1.SQL隐式游标的使用
SQL游标是oracle的内置游标,SQL游标与当前会话有关,当前会话的更新(update),删除操作都会影响到SQL隐式游标的属性.
(1)查看SQL隐式游标的默认值
begin
if sql%isopen then
dbms_output.put_line('sql游标已打开');
else
dbms_output.put_line('sql游标未打开');
end if;
dbms_output.put_line('游标捕获记录数'||sql%rowcount);
end;
/
sql游标未打开
游标捕获记录数
由此可以,在没有进行任何操作时,游标SQL的状态为'未打开';游标SQL的捕获记录数为空.虽然无法获得SQL游标的有用信息,但是至少证明SQL游标是存在的.
(2)查询语句对SQL隐式游标的影响
declare emp_no number;
begin
select empno into emp_no from emp where empno=7934;
if sql%isopen then
dbms_output.put_line('sql游标已打开');
else
dbms_output.put_line('sql游标未打开');
end if;
dbms_output.put_line('游标捕获记录数'||sql%rowcount);
end;
/
sql游标未打开
游标捕获记录数1
(3)更新语句对sql游标的影响
begin
update emp set empno=empno+1;
if sql%isopen then
dbms_output.put_line('sql游标已打开');
else
dbms_output.put_line('sql游标未打开');
end if;
dbms_output.put_line('游标捕获记录数'||sql%rowcount);
end;
/
sql游标未打开
游标捕获记录数10
(4)SQL隐式游标的使用
SQL游标最常使用的属性为found和rowcount
在应用开发中,经常出现这种场景:一条数据传入数据库的记录,用户并不能确定该记录是否存在,如果存在需要对记录的各列进行更新,否则,需要插入该记录.
begin
update emp set ename='TQW' where empno='120';
if sql%rowcount=0 then
insert into emp(empno,ename) values('120','TWES');
end if;
end;
/
对于判断条件sql%rowcount=0 可以用sql%notfound代替
2.cursor for游标的使用
利用cursor for游标可以像使用普通循环语句一样处理select语句获得的每一天记录
for 游标变量 in (查询语句) loop
DML操作
end loop;
eg. begin
for emp in (select * from emp) loop
dbms_output.put_line(emp.ename||'-'||emp.job||'-'||emp.sal);
end loop;
end;
/
(三)显示游标和隐式游标总结
显示游标和隐式游标都可实现对记录集和循环操作.显示游标需要用户遵循声明,打开,捕获记录,操作记录和关闭等步骤.隐式游标则无需如此繁琐的步骤,而更接近于其他编程语言中的for循环.
虽然显示游标操作复杂,但使用上却更加灵活,例如,在打开游标时传递参数,可以创建更加灵活多样的游标.相对而言,隐式游标操作步骤简练,但用户不能进行人工干预,隐刺适用于简单的游标操作.
三.动态游标
1.动态游标简介
动态游标是指,在游标声明时,不指定其查询定义,而是在游标打开时进行定义.
动态游标又可以分为两类:强类型动态游标和弱类型动态游标.
2.强类型动态游标
强类型动态游标是指,在游标使用之前,虽未指定游标的查询定义,但是游标的类型已确定.也就是说游标所代表的记录类型必须确定.
type 游标类型 is ref cursor
return 记录类型
eg.
declare
type refDeptCur is ref cursor return dept%rowtype; --返回dept 行类型
deptCur refDeptCur;
deptData dept%rowtype;
begin
open deptCur for
select * from dept;
fetch deptCur
into deptData;
loop
exit when deptCur%notfound;
dbms_output.put_line(deptData.dname);
fetch deptCur
into deptData;
end loop;
close deptCur;
end;
3.弱类型动态游标
弱类型动态游标虽然在查询上具有一定的灵活性,但所返回的记录类型是一定的,有时候在游标定义时,无法确定其记录类型,那么使用弱类型动态游标是一个较好的选择.
type 游标类型 is ref cursor
eg.
declare
type refEmpCur is ref cursor; --定义动态游标
empCur refEmpCur; --声明变量为refEmpCur游标变量
empData emp%rowtype; --声明empData为emp表的行类型
begin
open empCur for --打开游标存储emp表数据
select * from emp;
loop
exit when empCur%notfound;
fetch empCur
into empData;
dbms_output.put_line('编号:' || empData.empno || ' 姓名:' || empData.ename);
end loop;
close empCur;
end;
四.游标小结
最常用的是显示静态游标,用户可以手动控制显示游标的生命周期.
隐式游标适用于对于简单查询进行处理的场合.
静态游标总是在声明游标时,指定游标的查询定义,而动态游标则允许游标的查询定义在打开时指定,弱类型动态游标则进一步放宽限制--可以利用同一游标来获得不同数据结构中的记录.
[静态游标]
↓ --声明时不指定查询定义
[强类型动态游标]
↓ --声明时不指定返回类型
[弱类型动态游标]
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/26918004/viewspace-752825/
,如需转载,请注明出处,否则将追究法律责任。