游标的使用

一、游标概念

游标是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    --释放游标 

仅用于个人备忘。

 

posted @ 2022-09-21 15:13  给自己个晚安  阅读(306)  评论(0)    收藏  举报