一、什么是游标
游标:用来查询数据库,获取记录集合(结果集)的指针,可以让开发者一次访问一行
结果集,在每条结果集上做操作
从表中检索出结果集,从中每次指向一条记录进行交互的机制。
用来管理从数据源返回的数据的属性(结果集)。这些属性包括并发管理、在结果集中的位置、返回的行数,以及是否能够在结果集中向前和/或向后移动(可滚动性)。
游标跟踪结果集中的位置,并允许对结果集逐行执行多个操作,在这个过程中可能返回至原始表,也可能不返回至原始表。
换句话说,游标从概念上讲基于数据库的表返回结果集。
游动的光标(指针),可以指向一个结果集,通过游标的移动逐行提取每一行的记录 。
用来查询数据库,获取记录集合(结果集)的指针,可以让开发者一次访问一行结果集,在每条结果集上作操作。
用来存储多条查询数据的一种数据结构(结果集),它有一个指针,用来从上往下移动,从而达到遍历每条记录的作用。
由于它指示结果集中的当前位置 ,就像计算机屏幕上的光标指示当前位置一样,“游标”由此得名。
用于临时存储一个查询返回的多行数据(结果集,类似于Java的Jdbc连接返回的ResultSet集合),通过遍历游标,可以逐行访问处理该结果集的数据。
二、游标的作用
- 指定结果集中特定行的位置
- 基于当前的结果集位置检索一行或连续的几行
- 在结果集的当前位置修改行中的数据
- 对其它用户所做的数据更改定义不同的敏感性级别
- 可以以编程的方式访问数据库
程序语言是面向记录的,一组变量一次只能存放一个变量或者一条记录,无法直接接收数据库中的查询结果集引入游标就解决了这个问题。
三、什么时候避免使用游标
在想要使用游标的时候应该考虑:“是否有办法避免使用游标?”
因为游标的效率较差,如果游标操作的数据超过一万行,就应该改写代码了。
如果使用了游标,就要尽量避免在游标循环中再进行表连接的操作。
四、游标的类型
游标分为 静态游标 和 动态游标。
1. 静态游标
1.1 显式游标
用户显示声明的游标,即指定结果集。当查询返回结果超过一行时,就需要一个显式游标。用户自己写的sql语句,编译时能明确知道sql语句
1.2 隐式游标
所有DML语句(增、删、改、查询单条记录)为隐式游标,该变量名不需要用户自己声明,它由系统帮我们定义,叫SQL。使用时不需要声明隐式游标,它由系统定义。
隐式游标的使用:通过**%rowcour**判断是否使用了。
属性 | 描述 |
---|---|
%found | 布尔类型数据,当用户使用DML操作数据时,该属性返回true |
%notfound | 布尔型数据,如果执行DML操作时没有返回的数据行(在游标中找不到元素的时候)就返回true,否则返回false。通常用来判断是否退出循环。 |
%isopen | 布尔型数据,判断游标是否打开,该属性对任何的隐式游标总是返回false,表示游标已打开。 |
%rowcount | 整型数据,返回更新操作的行数或 select into 返回的行数。 |
2. 动态游标(REF游标)
是在执行前SQL语句是未知的游标,当执行时才知道所要执行的SQL语句的游标,动态关联结果集的临时对象。
2.1 强类型游标
规定返回类型。
2.2 弱类型游标
不规定返回类型,可以获取任何结果集。
五、游标的语法结构
cursor 游标名称 [(parameter[,parameter]...)]
[return 返回值类型] is selectSQL语句
语法解释:
cursor:声明一个游标
parameter:可选参数,用于指定参数类型、模式等
return:可选,指定游标的返回类型
SQL语句:需要处理的select语句,不能含into子句
--游标的使用方法: 声明 -> 打开 -> 读取 -> 关闭
--1.声明游标
declare
cursor 游标名称[参数列] is selectSQL语句
--2.打开游标
begin
open 游标名称
--3.读取游标数据
loop
fetch 游标名称 into 变量;
exit when 游标名称%notfound;
end loop;
--4.关闭游标
close 游标名称;
end;
六、游标的使用案例
读取单行记录
案例1:使用游标查询emp表中员工的姓名和工资
declare
--声明游标
cursor test01 is select ename,sal from emp;
--声明一个变量用来存储游标中获取来的数据
v_name emp.ename%type;
v_sal emp.sal%type;
begin
open test01;
fetch test01 into v_name,v_sal;
dbms_output.put_line(v_name || ' ' || v_sal);
close test01;
end;
案例2:使用游标查询emp表中所有员工的姓名
declare
--声明游标
cursor test02 is select ename from emp;
--声明一个变量用来存储游标中获取来的数据
v_name emp.ename%type;
begin
open test02;
fetch test02 into v_name;
dbms_output.put_line(v_name);
close test02;
end;
游标的多行读取(loop循环、while循环和for循环)
案例1:使用游标查询emp表中所有员工的姓名和工资,并将其依次打印出(loop循环)
declare
cursor cursor1 is select ename,sal from emp;
v_ename emp.ename%type;
v_sal emp.sal%type;
begin
open cursor1;
loop
fetch cursor1 into v_ename,v_sal;
exit when cursor1%notfound;
dbms_output.put_line(v_ename || ' ' || v_sal);
end loop;
close cursor1;
end;
案例2:使用游标查询emp表中所有员工的姓名和工资,并将其依次打印出(while循环)
declare
cursor cursor2 is select ename,sal from emp;
v_ename emp.ename%type;
v_sal emp.sal%type;
begin
open cursor2;
fetch cursor2 into v_ename,v_sal;
while cursor2%found loop
fetch cursor2 into v_ename,v_sal;
dbms_output.put_line(v_ename || ' ' || v_sal);
end loop;
close cursor2;
end;
案例3:使用游标查询emp表中所有员工的姓名和工资,并将其依次打印出(for循环)
--for循环自动打开游标,循环结束自动关闭游标
declare
cursor cursor3 is select ename,sal from emp;
v_ename emp.ename%type;
v_sal emp.sal%type;
begin
for cursor3_1 in cursor3 loop
v_ename := cursor3_1.ename;
v_sal := cursor3_1.sal;
dbms_output.put_line(v_ename || ' ' || v_sal);
end loop;
end;
带参数的游标
案例1:使用游标根据员工标号获取emp表中的员工姓名
----一般方法
declare
cursor cursor1 is select ename from emp where empno=7788;
v_name emp.ename%type;
begin
open cursor1;
loop
fetch cursor1 into v_name;
exit when cursor1%notfound;
dbms_output.put_line(v_name);
end loop;
close cursor1;
end;
案例2:使用游标查询并打印某部门的员工的姓名和薪资,部门编号为运行时手动输入
declare
cursor cursor1(empno_test emp.empno%type) is select ename,sal from emp where empno=empno_test;
v_name emp.ename%type;
v_sal emp.sal%type;
begin
open cursor1(7788);
loop
fetch cursor1 into v_name,v_sal;
exit when cursor1%notfound;
dbms_output.put_line(v_name || v_sal);
end loop;
close cursor1;
end;