(sql补充)关于游标

游标的定义:

在Oracle中,使用 SQL语句(例如,SELECT、INSERT、UPDATE、DELETE等)进行查询、修改、插入、删除等操作时,数据库管理系统为在内存中为其分配一个区域,这个区域是一段上下文的缓冲区。在这段区域中包含了SQL语句处理过程的必要信息。游标就是指向该段上下文缓冲区中数据的指针。

在PL/SQL中使用游标方便的控制上下文缓冲区以及语句处理过程中数据的变化。如果希望对结果集中的数据进行处理,就需要声明一个指向这个结果集的游标。通过使用游标,不仅可以查询数据库中的记录,对查询的结果集中的每一行记录执行不同的操作,也可以基于游标的位置对数据表中的记录进行更新操作(例如,修改数据、删除数据等)。

游标有两种类型,一种是隐式游标,一种是显式游标。对所有的SQL数据操作语句,PL/SQL都会为其声明一个隐式游标。使用游标可以从含有多条记录的结果集中提取一条数据记录。当然,也可以使用游标从结果集中返回多条数据记录。如果希望从结果集中返回多条数据记录,就需要声明一个显式游标,并通过游标FOR循环或者使用BULK COLLECT子句批量绑定数据的方式得到多条数据记录。

游标的优缺点:

SQL游标的优点是可以方便从一个结果集中进行循环遍历数据在进行操作。
1、游标允许应用程序对查询语句select 返回的行结果集中每一行进行相同或不同的操作,而不是一次对整个结果集进行同一种操作;
2、它还提供对基于游标位置而对表中数据进行删除或更新的能力;
3、游标把作为面向集合的数据库管理系统和面向行的程序设计两者联系起来,使两个数据处理方式能够进行沟通。
然尔游标也有缺点——复杂和低效,是游标的最大缺点,也是致使很多时候在使用存储过程中没有想到游标的主要原因。

声明游标

要想使用游标提取数据,首先需要声明一个游标。声明游标时,需要为游标定义一个名字,并为其指定一个对应的SELECT语句。其声明游标的语法规则如下:
CURSOR cursor_name IS select_statement;
其中,cursor_name表示游标的名字;select_statement是一个与cursor_name游标对应的查询语句。这里的SELECT查询语句中不能含有INTO子句。游标的声明可以放到PL/SQL语句块、子程序或者包的声明部分。
注意:在引用游标之前,必须使用声明游标的语句对其进行声明。如果在引用之前没有对游标进行声明,则这样的引用就是非法的。

打开游标

在声明完一个游标之后,就可以使用OPEN语句打开这个游标了。只有在打开了游标之后,才可以执行相关数据提取操作。打开游标的语法规则如下:
OPEN cursor_name;
其中,cursor_name表示前面已经声明的游标的名字。当游标打开之后,就可以执行其对应的SELECT语句的操作,并可以将数据查询的结果放入到游标的缓冲区中。使用OPEN语句打开一个游标,其对应的SELECT语句中的结果集中的行并没有被选取,如果想使游标取得数据,需要使用FETCH语句。

从游标中取得结果

在完成了声明游标和打开游标的操作之后,就可以使用游标检索结果集中的数据了。使用游标检索结果集中的数据是使用FETCH语句来完成。其语法规则如下:
FETCH cursor_name INTO vairable1 [ vairable2…]
其中,cursor_name为游标的名字,该游标需要是已经在前面声明并打开的游标。vairable1、vairable2表示的是声明的变量。这里的变量可以是一个标量变量,也可以是一个记录或者PL/SQL中的集合变量。多个变量之间需要用逗号分割。
注意:FETCH语句中需要包含INTO子句。而声明游标时,select_statement查询语句不能包含INTO子句。

关闭游标

当查询的结果集检索完成之后,就可以关闭游标了。关闭游标是使用CLOSE语句来完成的。关闭游标后,与游标相关的资源将会被释放。关闭游标的语法规则如下:
CLOSE cursor_name;
其中,cursor_name表示关闭游标的名字。这里的cursor_name是前面已经打开的游标名。游标被关闭后还可以重新将其打开。

游标循环

在使FETC用H语句提取数据记录时,每次只能从结果集中提取一条记录,取得该条记录之后,将游标下移,指向当前记录的下一条记录。在实际应用中,一般都需要对结果集中的所有数据记录进行遍历,并对每一条数据记录进行处理,这就需要在FETCH语句通过使用循环语句来实现。

简单LOOP循环

WHILE循环

游标FOR循环

-----------------------------------------------------------------------------------------推荐一篇来自51cto的文章----------------------------------------------------------------------------------------------------------
用SQL游标遍历循环数据的方法
2010-09-09 16:40 佚名 互联网 我要评论(1) 字号:T | T


SQL游标的优点是可以方便从一个结果集中进行循环遍历数据在进行操作,下面就将为您介绍用SQL游标对数据进行遍历循环操作的方法,供您参考。

AD:51CTO云计算架构师峰会 抢票进行中!


如果对数据进行遍历循环操作,通过SQL的游标就可以实现,下面就为您详细介绍该方法,供您参考,希望对您学习SQL数据库能够有所帮助。

SQL游标的优点是可以方便从一个结果集中进行循环遍历数据在进行操作。
1、游标允许应用程序对查询语句select 返回的行结果集中每一行进行相同或不同的操作,而不是一次对整个结果集进行同一种操作;
2、它还提供对基于游标位置而对表中数据进行删除或更新的能力;
3、游标把作为面向集合的数据库管理系统和面向行的程序设计两者联系起来,使两个数据处理方式能够进行沟通。
然尔游标也有缺点——复杂和低效,是游标的最大缺点,也是致使很多时候在使用存储过程中没有想到游标的主要原因。

下面是在实际工作中的一个游标实例的应用,通过游标把A表的数据的一列值复制到B表的列当中,其中二个表都有相同的UID字段,条件是对相同UID的数据进行复制.

declare @level varchar(100)
declare @uid varchar(100)
declare cur cursor--定义一个游标
read_only
for select egg_code.user_id,egg_prize_level
from egg_code inner join egg_prize on egg_prize.user_id=egg_code.user_id--为所获得的数据集指定游标

open cur--打开游标
fetch next from cur into @uid,@level--把提取操作的列数据放到局部变量中
while(@@fetch_status=0)--返回被 FETCH 语句执行的最后游标的状态,而不是任何当前被连接打开的游标的状态。

begin
--print '等级:'+@level+'--------------用户ID:'+@uid

update egg_code set prize_level=@level where user_id=@uid--执行操作

--提前下一位信息
fetch next from cur into @uid,@level
end
close cur--关闭游标
deallocate cur--删除游标
go

使用游标的顺序: 声名游标、打开游标、读取数据、关闭游标、删除游标。
由于 @@FETCH_STATUS 对于在一个连接上的所有游标是全局性的,要小心使用 @@FETCH_STATUS 。在执行一条 FETCH 语句后,必须在对另一游标执行另一 FETCH 语句前测试 @@FETCH_STATUS 。在任何提取操作出现在此连接上前,@@FETCH_STATUS 的值没有定义。
例如,用户从一个游标执行一条 FETCH 语句,然后调用一个存储过程,此存储过程打开并处理另一个游标的结果。当控制从被调用的存储过程返回后,@@FETCH_STATUS 反映的是在存储过程中执行的最后的 FETCH 语句的结果,而不是在存储过程被调用之前的 FETCH 语句的结果。
使用上面的游标是泉州SEO在一次网站砸金蛋活动中,二个表的数据在使用的过程中有部份后期改到程序致使有部份数据无法同步,导致前台查询的时候所用到的表无法查到相关的数据,没用游标进行操作之前试过只用简单的SQL语句去实现这样的同步功能,但是始终无法实现,所以只能使用游标来实现。

原文地址:https://www.cnblogs.com/zhujianxipan/p/3146893.html