sql 游标如何循环
3个回答
展开全部
SQL游标的优点是可以方便从一个结果集中进行循环遍历数据在进行操作,下面就将为您介绍用SQL游标对数据进行遍历循环操作的方法,供您参考。
AD:
如果对数据进行遍历循环操作,通过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语句去实现这样的同步功能,但是始终无法实现,所以只能使用游标来实现。
AD:
如果对数据进行遍历循环操作,通过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语句去实现这样的同步功能,但是始终无法实现,所以只能使用游标来实现。
展开全部
我以前写的一个存储过程,用的就是游标,功能是遍历某一个数据库中所有的表,把记录大于10000的表名和记录数输出屏幕,完整代码如下,希望对LZ有帮助吧:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--重点开始了
CREATE PROCEDURE [dbo].[hrmis_counts]
AS
BEGIN
--声明游标
Declare MyCursor Cursor
For Select name From hrmis..sysobjects where xtype='u'
--"hrmis"是我需要查询的数据库名称
--"xtype='u'"的意思是:只查询用户表,系统表不要,但可能会出错,网上有资料防止这种意外,至少我没有报错,就不理了。
--打开游标
Open MyCursor
--定义变量
Declare @tableName nvarchar(max),@sql nvarchar(max),@counts int
Fetch Next From MyCursor Into @tableName
While @@Fetch_status = 0
--@@Fetch_status = 0是指:游标未到末尾
Begin
Set @sql = 'Select @counts=counts(*) From '+ @tableName
--print @sql
--Exec(@sql)
--上面这句会报错的“@counts未定义之类的,我忘了,有兴趣自己试试”,反正不能直接执行就是了。
--正确的写法是下面这句
Exec sp_executesql @sql,N'@counts Int out',@counts out
--好吧,我承认我也不太了解这条语句的含意,但这是不重点,重点是,它执行成功了。
If @counts > 10000
--只显示记录数大于1W的表名(这里随意就好了,不要也行)
print (Convert(nvarchar(max),@counts) +'......'+ @tableName)
Fetch Next From MyCursor Into @tableName
End
--关闭游标
Close MyCursor
Deallocate MyCursor
End
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--重点开始了
CREATE PROCEDURE [dbo].[hrmis_counts]
AS
BEGIN
--声明游标
Declare MyCursor Cursor
For Select name From hrmis..sysobjects where xtype='u'
--"hrmis"是我需要查询的数据库名称
--"xtype='u'"的意思是:只查询用户表,系统表不要,但可能会出错,网上有资料防止这种意外,至少我没有报错,就不理了。
--打开游标
Open MyCursor
--定义变量
Declare @tableName nvarchar(max),@sql nvarchar(max),@counts int
Fetch Next From MyCursor Into @tableName
While @@Fetch_status = 0
--@@Fetch_status = 0是指:游标未到末尾
Begin
Set @sql = 'Select @counts=counts(*) From '+ @tableName
--print @sql
--Exec(@sql)
--上面这句会报错的“@counts未定义之类的,我忘了,有兴趣自己试试”,反正不能直接执行就是了。
--正确的写法是下面这句
Exec sp_executesql @sql,N'@counts Int out',@counts out
--好吧,我承认我也不太了解这条语句的含意,但这是不重点,重点是,它执行成功了。
If @counts > 10000
--只显示记录数大于1W的表名(这里随意就好了,不要也行)
print (Convert(nvarchar(max),@counts) +'......'+ @tableName)
Fetch Next From MyCursor Into @tableName
End
--关闭游标
Close MyCursor
Deallocate MyCursor
End
GO
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
fetch next from 游标名 into 变量列表
while @@fetch_status=0
begin
.........
fetch next from 游标名 into 变量列表
end
while @@fetch_status=0
begin
.........
fetch next from 游标名 into 变量列表
end
本回答被网友采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询