Oracle-游标

举报
小奇JAVA 发表于 2022/07/03 00:28:20 2022/07/03
【摘要】 万般皆下品、惟有读书高 文章持续更新,可以微信搜索【小奇JAVA面试】第一时间阅读,回复【资料】获取福利,回复【项目】获取项目源码,回复【简历模板】获取简历模板,回复【学习路线图】获取学习路线图。 ...

万般皆下品、惟有读书高
文章持续更新,可以微信搜索【小奇JAVA面试】第一时间阅读,回复【资料】获取福利,回复【项目】获取项目源码,回复【简历模板】获取简历模板,回复【学习路线图】获取学习路线图。

在这里插入图片描述


一、游标的定义和类型

1、游标的基本概念

游标就是移动的光标,在oracle中,为了处理sql语句,在内存中会分配一个区域,又叫上下文区,整个区域是sql语句返回的数据集合,而游标就是指向这个上下文的指针。
使用游标,可以处理从数据库中返回的多行记录,逐个遍历和处理检索返回的记录集合。

2、游标的基本类型

游标分为两大类:静态游标和动态游标,其中静态游标又分为显示游标和隐式游标两种类型。
1、显示游标
显示游标是用户定义和操作的游标,用于处理使用select查询语句返回多行的查询结果,使用显示游标处理数据分为如下步骤:声明游标、打开游标、读取游标和关闭游标。
2、隐式游标
系统自动进行操作,用于处理DML语句的执行结果或者select查询返回的单行数据,使用时不需要进行声明、打开和关闭。
3、动态游标
显示游标在定义时与特定的查询绑定,其结构是不变的,而动态游标也称为游标变量,是一个指向多行查询结果的指针,不与特定的查询结果绑定,可以在打开游标变量时定义查询,可以返回不同结构的结果集。

3、静态游标属性

在静态游标中,不管是显式游标还是隐式游标,都具有%found,%notfound,%isopen和%rowcount等4个属性,可以通过这些属性获取SQL语句执行结果以及游标的状态信息。
1、%found:布尔型,判断是否检索到数据,如果检索到,属性值为true,否则为false。
2、%notfound:布尔型,与%found功能相反。
3、%isopen:布尔型,判断游标是否打开,如果打开,则返回属性值为true,否则为false。
4、%rowcount:数字型,返回受SQL语句影响的行数。
隐式游标的这4个属性在使用的时候,需要在属性前加入隐式游标的默认名称SQL,即SQL%found、SQL%notfound、SQL%isopen、SQL%rowcount。

二、游标的创建及使用

1、显示游标的创建与使用

1:声明游标

语法如下:

cursor 游标名称 [参数列表] is <select 语句>

  
 
  • 1

其中,参数列表是可选项 ,如果需要参数,其形式如下所示。

参数名称 [in] 数据类型 [{:=IDEFAULT} 参数值] 

  
 
  • 1

需要注意的是,参数只能定义数据类型,但是不能有大小,可以给参数设定一个默认值,此时,调用的时候如果没有参数数值传递给游标时,就使用这个默认值,参数可以有多个。
定义游标的时候需要注意以下几点。
1、游标必须在PL/SQL数据库的声明部分定义。
2、定义游标时并没有生成数据,只是将定义信息保存到数据字典中。
3、select 语句不能包含into子句。
例如,定义一个游标cur_stu,该游标用来读取student表中所有的学生姓名信息。

cursor cur_stu is select name from student;

  
 
  • 1

上面这个例子没有使用参数,下面这个例子使用了参数

cursor cur_stu(var_class in varchar2:='五班') is select name from student where class = var_class;

  
 
  • 1

在上面的例子中,游标定义了一个输入参数var_stu,数据类型为varchar2,但是要注意此时并没有定义长度,如果定义长度就错了。这个参数用来接收外部传来的值,如果调用游标时没有传入参数,则使用默认值“五班”,游标实现查询student表中班级为“五班”的所有员工的信息。

2:打开游标

游标定义完成后,还不能直接使用,在使用之前,必须先打开,打开游标的基本语法如下所示。

open 游标名称 [参数值]

  
 
  • 1

其中,参数值是可选项。如果在游标声明的时候定义了参数,并有初始化值,但打开的时候没有使用参数,则游标就使用定义时参数的初始值,如果打开的时候指定了参数值,则游标就使用这个参数值。同样,这里和声明时参数一样可以有多个。
游标打开后,系统将分配缓冲区,执行游标中select语句,把查询结果在缓冲区中缓存,游标指针指向缓冲区中返回结果集的第一个记录。
例如,下面例子打开游标cur_stu。

open cur_stu;

  
 
  • 1

如果带参数值,可以使用下面的语句。

open cur_stu('三班')

  
 
  • 1

上面这个带参数值的游标打开时,将“三班”赋值给游标中var_class,如果调用的时候没有传入参数,就使用默认的‘五班’来查询。

3:读取游标

游标打开后,缓冲区中是查询结果,此时可以使用游标把查询结果集合中的记录分别读取出来,基本语法如下所示。

fetch 游标名称 into <变量列表>|<记录变量>

  
 
  • 1

游标刚打开时,游标指针指向查询结果集合中的第一条记录,使用fetch…into…语句读取数据后,游标指针自动指向下一条记录。因此,可以把fetch…into…语句与循环结构相结合,读取缓冲区中的所有数据,可以使用上一节介绍的游标属性判断是否还有数据,数据个数等。
注意,游标指针只能增加,不能减少,即只能向下移动,不能后退。
此外,into子句中变量个数、顺序、数据类型都必须与缓冲区中每个记录的字段变量、顺序和数据类型一致,或者说与游标定义时select语句中的一样。也可以定义一个记录变量,来存储游标指向记录中的数据。比如下面的这个形式。

fetch cur_stu into v_id,v_name;

  
 
  • 1

上面语句将游标当前指向的记录中学生编号和学生姓名分别送到v_id和v_name变量中。

4:关闭游标

游标使用完后,要记得关闭,释放缓冲区所占用的系统资源,基本语法如下所示。

close 游标名称

  
 
  • 1

例如,下面语句关闭游标cur_stu

close cur_stu;

  
 
  • 1

5:使用游标查询student表中所有年龄大于20的学生基本信息。

declare
	var_name student.name%type;	--定义变量
	var_age student.age%type;
	cursor cur_age is select name,age from student where age > 20;
begin
	open cur_age;	--打开游标
	petch cur_age into var_name,var_age;	--读取游标
	while cur_age%found loop	--使用游标属性判断是否还有数据
		dbms_output.put_line<'年龄大于20的学生如下:'>;
		dbms_output.put_line<'学生姓名:' || var_name || ',学生年龄:' || var_age>;
		petch cur_age into var_name,var_age;
	end loop;	
	close cur_sal;	--关闭游标
end;

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

2、隐式游标的创建与使用

和显示游标不同,隐式游标是系统自动创建的,用于处理DML语句(例如insert、update、delete等指令)的执行结果或者select查询返回的单行数据,这时隐式游标是指向缓冲区的指针。使用时不需要进行声明、打开和关闭,因此不需要open、fetch、close这样的操作指令。隐式游标也有前述介绍的4种属性,使用时需要在属性前面加上隐式游标的默认名称SQL,因此隐式游标也叫SQL游标。

1、将student表中张三的学生年龄增加10岁,然后使用隐式游标的%rowcount属性输出涉及的员工数量

begin
	update student set age=age+10	--年龄增加10
	where name = '张三';
	if sql%notfound then	--是否有符合条件的记录
		dbms_output.put_line<'没有符合条件的学生'>;
	else
		dbms_output.put_line<'符合条件的学生数量为:' || sql%rowcount>;
	end if;
end;

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

3、动态游标的创建与使用

显示游标在定义时与特定的查询绑定,其结构是不变的,反映的是在显示游标打开的时刻当时的状态,此后如果再对数据库进行更新、删除或者插入,不会影响已经打开的游标。而动态游标也称为游标变量,是一个指向多行查询结果集的指针,不与特定的查询绑定,可以在打开游标变量时定义查询。
1、动态游标的定义
基本语法如下。

type 动态游标名称 is ref cursor [return 返回类型]

  
 
  • 1

其中,返回类型是可选项。

2、声明游标变量
基本语法如下所示。

变量名字 动态游标名称

  
 
  • 1

使用前面定义的动态游标名称声明游标变量。
例如,下面两条语句分别定义了一个动态游标stu_cursor,其返回类型是student数据表的行记录类型,然后使用所定义的动态游标声明了一个游标变量。

type stu_cursor is ref cursor return stuent%rowtype;
var_cursor stu_cursor;

  
 
  • 1
  • 2

3、打开游标变量
和前面显示游标一样,使用之前要打开的游标,不过由于在动态游标定义的时候并没有对应的查询语句,因此在打开游标变量的时候要同时指定游标变量所对应的查询语句,当执行打开游标操作时,系统会执行对应的查询语句,将查询结果放入游标变量对应的缓冲区中。语法如下

open 游标变量 for <select 语句>

  
 
  • 1

l例如,游标变量对应的查询语句如下所示。

open var_cursor for select * from student;

  
 
  • 1

4、检索游标变量
和前面介绍的显示游标检索的方法一样,都是使用fetch…into…语句存储当前游标指向的记录值,并结合简单循环结构显示查询结果中的记录。

5、关闭游标变量
游标变量使用完,应及时关闭以释放缓冲区空间。语法如下。

close 游标变量

  
 
  • 1

三、游标for循环

由于使用游标定义的查询或者操作返回多个记录集合到缓冲区,要想通过游标访问每条记录,需要结合循环结果使用,现在介绍两种循环结构的使用。
1、使用基本的loop循环结构,其使用语法如下。

loop
fetch...into...
exit when 游标名称%notfound
...
end loop;

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

2、使用while循环检索游标,其使用语法如下。

fetch...into...
while 游标名称%found loop
fetch...into...;
......
end loop;

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

前面这两种使用fetch…into…语句结合循环结构显示记录的时候,在使用游标之前还要打开游标,使用结束后要关闭游标,同时在使用过程中还要判断数据记录缓冲区中是否还有数据。此外,我们可以使用for循环结合游标检索数据,及游标for循环,这种方式不需要打开游标和关闭游标,也不需要使用fetch…into…语句检索数据。其语法格式如下。

for 循环变量 in 游标名称 loop
语句序列;
end loop;

  
 
  • 1
  • 2
  • 3

其中,循环变量可以使任意合法的变量名称,系统会隐含地定义该变量的数据类型为游标名称%rowtype,然后自动打开游标,从缓冲区中取出当前游标指向的记录并放入循环变量中,并判断%found属性,以确定是否存在数据,如果数据已经检索完,则结束循环,并自动关闭游标。

1、输出student中年龄为20的所有学生的姓名。

declare
	cursor cur_stu is select * from student where age = 20;	--定义游标
begin
	for var_stu in cur_stu loop	--for循环游标
		dbms_output.put_line<'学生姓名:' || var_stu.name>;	--显示结果
	end loop;
end;

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

四、总结

这里的相关内容还没有整理完毕,文章后面持续更新,建议收藏。

文章中涉及到的命令大家一定要像我一样每个都敲几遍,只有在敲的过程中才能发现自己对命令是否真正的掌握了。

可以微信搜索【小奇JAVA面试】第一时间阅读,回复【资料】获取福利,回复【项目】获取项目源码,回复【简历模板】获取简历模板,回复【学习路线图】获取学习路线图。

文章来源: xiaoqijava.blog.csdn.net,作者:旷世奇才李先生,版权归原作者所有,如需转载,请联系作者。

原文链接:xiaoqijava.blog.csdn.net/article/details/125568754

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。