游标的使用
一、游标概念
游标是SQL Server的一种数据访问机制,它允许用户访问单独的数据行。用户可以对每一行进行单独的处理,从而降低系统开销和潜在的阻隔情况,用户也可以使用这些数据生成的SQL代码并立即执行或输出。
游标主要用于存储过程,触发器和 T_SQL脚本中,它们使结果集的内容可用于其它T_SQL语句在查看或处理结果集中向前或向后浏览数据的功能。类似与C语言中的指针,它可以指向结果集中的任意位置,当要对结果集进行逐条单独处理时,必须声明一个指向该结果集中的游标变量。
优点:
游标能从包括多条记录的结果集中每次提取一条记录,由结果集和指向特定记录的游标位置组成。
游标具有以下优点:
允许程序对由SELECT查询语句返回的行集中的每一次执行相同或不同的操作,而不是对整个集合执行同一个操作
提供对基于游标位置中的行进行删除和更新的能力。
游标作为数据库管理系统和应用程序设计之间的桥梁,将两种处理方式连接起来。
分类:
Transact_SQL游标:服务器上实现,由SQL语句管理
应用程序编程接口(API)服务器游标:服务器上实现,客户端调用API游标函数,由接口或驱动程序传给服务器
客户端游标:在客户端缓存所有结果集中的行,由API函数通过接口或驱动程序调用缓存结果集中的行
只进游标:不支持滚动,支持从头到尾顺序读取
静态游标:始终只读,打开游标时结果集建立在tempdb中,按照打开时的原样显示结果集。 静态游标不会显示打开游标以后在数据库中新插入的行。
由键驱动的游标: 各行的成员身份和顺序固定。由键集驱动的游标由一组唯一标识符(键)控制,这组键成为键集。
动态游标:当滚动游标时,动态游标反映结果集中所做的所有更改。
二、游标的操作
1.声明
游标构成:游标结果集+游标位置
游标结果集:游标的SELECT语句返回的行集合
游标位置:指向这个结果集中某一行的指针。
创建游标简单应用
declare test_cur cursor for --创建游标
select employeeName,employeeDept from tb_employee;
open test_cur --打开游标
fetch next from test_cur --从游标变量中读取值
while @@FETCH_STATUS=0 --判断fetch语句是否执行成功(0:成功 -1:fetch语句失败或此行不在结果集中 -2:被提取的行不在)
begin
fetch next from test_cur --读取游标变量中的数据
end
close test_cur --关闭游标
deallocate test_cur --释放游标
2.Fetch语法格式
FETCH [ [ NEXT | PRIOR | FIRST | LAST | ABSOLUTE { n | @nvar } | RELATIVE { n | @nvar } ] FROM
ABSOLUTE:如果n或@nvar为正,则返回从游标头开始向后n行的第n行,并将返回行变成新的当前行。如果n或@nvar为负,则返回从游标末尾开始向前的n行的第n行,并将返回行变成新的当前行。如果n或@nvar为0,则不返回行。n必须是整数常量,并且@nvar的数据类型必须为int、tinyint或smallint.
RELATIVE:如果n或@nvar为正,则返回从当前行开始向后的第n行。如果n或@nvar为负,则返回从当前行开始向前的第n行。如果n或@nvar为0,则返回当前行,对游标第一次提取时,如果在将n或@nvar设置为负数或0的情况下指定FETCH RELATIVE,则不返回行,n必须是整数常量,@nvar的数据类型必须是int、tinyint或smallint.
示例:
begin tran DECLARE demo_cursor CURSOR --声明游标 FOR SELECT [meterNo],[copyTime],[currentShow] FROM dbo.[Android_CopyDataTemp] where [copyState] =1 order by _id desc OPEN demo_cursor --打开游标 declare @Parm_Number nvarchar(20) declare @ReadTime datetime declare @OcrRead nvarchar(10) FETCH NEXT FROM demo_cursor into @Parm_Number ,@ReadTime, @OcrRead --获取游标的下一行数据 WHILE @@FETCH_STATUS = 0 --FETCH语句执行成功 BEGIN EXEC loopback.[HHMeterMangrZHGX(0629)].dbo.sp_insert @Parm_Number, @ReadTime,@ReadTime,@OcrRead; --print @Parm_Number; print @ReadTime;print @OcrRead; FETCH NEXT FROM demo_cursor into @Parm_Number ,@ReadTime, @OcrRead --获取游标的下一行 End CLOSE demo_cursor --关闭游标 DEALLOCATE demo_cursor --释放游标
示例2:
DECLARE demo_cursor CURSOR --声明游标 FOR SELECT [meterNo] FROM [dbo].[Android_GroupBind] as gb inner join [dbo].[Android_GroupInfo] as g on gb.groupNo =g.groupNo inner join [dbo].[Android_BookInfo] as b on b.bookNo = g.bookNo where b.bookNo='0000001293' OPEN demo_cursor --打开游标 declare @Parm_Number nvarchar(20) FETCH NEXT FROM demo_cursor into @Parm_Number --获取游标的下一行数据 WHILE @@FETCH_STATUS = 0 --FETCH语句执行成功 BEGIN INSERT INTO [dbo].[Android_CopyDataTemp] ([meterNo] ,[lastShow] ,[lastDosage] ,[currentShow] ,[currentDosage] ,[unitPrice] ,[printFlag] ,[meterState] ,[copyWay] ,[copyState] ,[copyTime] ,[copyMan] ,[Operator] ,[operateTime] ,[isBalance] ,[Remark] ,[meterName] ,[dBm] ,[elec]) SELECT TOP 1 [meterNo] ,[lastShow] ,[lastDosage] ,[currentShow] ,[currentDosage] ,[unitPrice] ,[printFlag] ,[meterState] ,[copyWay] ,[copyState] ,[copyTime] ,[copyMan] ,[Operator] ,[operateTime] ,[isBalance] ,[Remark] ,[meterName] ,[dBm] ,[elec] FROM [dbo].[Android_CopyData] where meterno=@Parm_Number order by copyTime desc FETCH NEXT FROM demo_cursor into @Parm_Number --获取游标的下一行 End CLOSE demo_cursor --关闭游标 DEALLOCATE demo_cursor --释放游标
仅用于个人备忘。

浙公网安备 33010602011771号