SQL Server游标

什么是游标

结果集,结果集就是select查询之后返回的所有行数据的集合。

游标则是处理结果集的一种机制吧,它可以定位到结果集中的某一行,多数据进行读写,也可以移动游标定位到你所需要的行中进行操作数据。

一般复杂的存储过程,都会有游标的出现,他的用处主要有:

  1. 定位到结果集中的某一行。
  2. 对当前位置的数据进行读写。
  3. 可以对结果集中的数据单独操作,而不是整行执行相同的操作。
  4. 是面向集合的数据库管理系统和面向行的程序设计之间的桥梁。

游标的分类

根据游标检测结果集变化的能力和消耗资源的情况不同,SQL Server支持的API服务器游标分为一下4种:

  • 静态游标: 静态游标的结果集,在游标打开的时候建立在TempDB中,不论你在操作游标的时候,如何操作数据库,游标中的数据集都不会变。例如你在游标打开的时候,对游标查询的数据表数据进行增删改,操作之后,静态游标中select的数据依旧显示的为没有操作之前的数据。如果想与操作之后的数据一致,则重新关闭打开游标即可。
  • 动态游标:这 个则与静态游标相对,滚动游标时,动态游标反应结果集中的所有更改。结果集中的行数据值、顺序和成员在每次提取时都会变化。所有用户做的增删改语句通过游 标均可见。如果使用API函数或T-SQL Where Current of子句通过游标进行更新,他们将立即可见。在游标外部所做的更新直到提交时才可见。
  • 只进游标:只进游标不支持滚动,只支持从头到尾顺序提取数据,数据库执行增删改,在提取时是可见的,但由于该游标只能进不能向后滚动,所以在行提取后对行做增删改是不可见的。
  • 键集驱动游标:打开键集驱动游标时,该有表中的各个成员身份和顺序是固定的。打开游标时,结果集这些行数据被一组唯一标识符标识,被标识的列做删改时,用户滚动游标是可见的,如果没被标识的列增该,则不可见,比如insert一条数据,是不可见的,若可见,须关闭重新打开游标。

静态游标在滚动时检测不到表数据变化,但消耗的资源相对很少。动态游标在滚动时能检测到所有表数据变化,但消耗的资源却较多。键集驱动游标则处于他们中间,所以根据需求建立适合自己的游标,避免资源浪费。。

游标的生命周期

游标的生命周期包含有五个阶段:声明游标、打开游标、读取游标数据、关闭游标、释放游标。

 1.声明游标,语法

DECLARE cursor_name CURSOR [ LOCAL | GLOBAL ]
     [ FORWARD_ONLY | SCROLL ]
     [ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]
     [ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]
     [ TYPE_WARNING ]
     FOR select_statement
     [ FOR UPDATE [ OF column_name [ ,...n ] ] ]

参数说明:

  • cursor_name:游标名称。
  • Local:作用域为局部,只在定义它的批处理,存储过程或触发器中有效。
  • Global:作用域为全局,由连接执行的任何存储过程或批处理中,都可以引用该游标。
  • [Local | Global]:默认为local。
  • Forward_Only:指定游标智能从第一行滚到最后一行。Fetch Next是唯一支持的提取选项。如果在指定Forward_Only是不指定Static、KeySet、Dynamic关键字,默认为Dynamic游标。如果Forward_Only和Scroll没有指定,Static、KeySet、Dynamic游标默认为Scroll,Fast_Forward默认为Forward_Only
  • Static:静态游标
  • KeySet:键集游标
  • Dynamic:动态游标,不支持Absolute提取选项
  • Fast_Forward:指定启用了性能优化的Forward_Only、Read_Only游标。如果指定啦Scroll或For_Update,就不能指定他啦。
  • Read_Only:不能通过游标对数据进行删改。
  • Scroll_Locks:将行读入游标是,锁定这些行,确保删除或更新一定会成功。如果指定啦Fast_Forward或Static,就不能指定他啦。
  • Optimistic:指定如果行自读入游标以来已得到更新,则通过游标进行的定位更新或定位删除不成功。当将行读入游标时,sqlserver不锁定行,它改用timestamp列值的比较结果来确定行读入游标后是否发生了修改,如果表不行timestamp列,它改用校验和值进行确定。如果已修改改行,则尝试进行的定位更新或删除将失败。如果指定啦Fast_Forward,则不能指定他。
  • Type_Warning:指定将游标从所请求的类型隐式转换为另一种类型时向客户端发送警告信息。
  • For Update[of column_name ,....] :定义游标中可更新的列。

2.声明一个动态游标

declare orderNum_02_cursor cursor scroll
for select OrderId from bigorder where orderNum=‘ZEORD003402‘

3.打开游标

--打开游标语法
open [ Global ] cursor_name | cursor_variable_name

cursor_name:游标名,cursor_variable_name:游标变量名称,该变量引用了一个游标。

--打开游标
open orderNum_02_cursor

4.提取数据

--提取游标语法
Fetch
[ [Next|prior|Frist|Last|Absoute n|Relative n ]
from ]
[Global] cursor_name
[into @variable_name[,....]]

参数说明:

  • Frist:结果集的第一行
  • Prior:当前位置的上一行
  • Next:当前位置的下一行
  • Last:最后一行
  • Absoute n:从游标的第一行开始数,第n行。
  • Relative n:从当前位置数,第n行。
  • Into @variable_name[,...] : 将提取到的数据存放到变量variable_name中。

例子:

--提取数据
fetch first from orderNum_02_cursor
fetch relative 3 from orderNum_02_cursor
fetch next from orderNum_02_cursor
fetch absolute 4 from orderNum_02_cursor
fetch next from orderNum_02_cursor
fetch last from orderNum_02_cursor
fetch prior from orderNum_02_cursor
select * from bigorder where orderNum=‘ZEORD003402‘

结果(对比一下,就明白啦):

例子:

--提取数据赋值给变量
declare @OrderId int
fetch absolute 3 from orderNum_02_cursor into @OrderId
select @OrderId as id
select * from bigorder where orderNum=‘ZEORD003402‘

结果:

通过检测全局变量@@Fetch_Status的值,获得提取状态信息,该状态用于判断Fetch语句返回数据的有效性。当执行一条Fetch语句之后,@@Fetch_Status可能出现3种值:0,Fetch语句成功。-1:Fetch语句失败或行不在结果集中。-2:提取的行不存在。

这个状态值可以帮你判断提取数据的成功与否。

declare @OrderId int
fetch absolute 3 from orderNum_02_cursor into @OrderId
while @@fetch_status=0  --提取成功,进行下一条数据的提取操作
 begin
   select @OrderId as id
   fetch  next from orderNum_02_cursor into @OrderId  --移动游标
 end 

5.利用游标更新删除数据

--游标修改当前数据语法
Update 基表名 Set 列名=值[,...] Where Current of 游标名
--游标删除当前数据语法
Delete 基表名  Where Current of 游标名

---游标更新删除当前数据
---1.声明游标
declare orderNum_03_cursor cursor scroll
for select OrderId ,userId from bigorder where orderNum=‘ZEORD003402‘
--2.打开游标
open orderNum_03_cursor
--3.声明游标提取数据所要存放的变量
declare @OrderId int ,@userId varchar(15)
--4.定位游标到哪一行
fetch First from orderNum_03_cursor into @OrderId,@userId  --into的变量数量必须与游标查询结果集的列数相同
while @@fetch_status=0  --提取成功,进行下一条数据的提取操作
 begin
   if @OrderId=122182
     begin
     Update bigorder Set UserId=‘123‘ Where Current of  orderNum_03_cursor  --修改当前行
     end
   if @OrderId=154074
      begin
      Delete bigorder Where Current of  orderNum_03_cursor  --删除当前行
      end
   fetch next from orderNum_03_cursor into @OrderId ,@userId  --移动游标
 end  

6.关闭游标

游标打开后,服务器会专门为游标分配一定的内存空间存放游标操作的数据结果集,同时使用游标也会对某些数据进行封锁。所以游标一旦用过,应及时关闭,避免服务器资源浪费。

--关闭游标语法
close [ Global ] cursor_name | cursor_variable_name
--关闭游标
close orderNum_03_cursor

7.删除游标

删除游标,释放资源

--释放游标语法
deallocate  [ Global ] cursor_name | cursor_variable_name
--释放游标
deallocate orderNum_03_cursor
时间: 2024-10-08 14:44:50

SQL Server游标的相关文章

SQL Server 游标

什么是游标 结果集,结果集就是select查询之后返回的所有行数据的集合. 游标则是处理结果集的一种机制吧,它可以定位到结果集中的某一行,多数据进行读写,也可以移动游标定位到你所需要的行中进行操作数据. 一般复杂的存储过程,都会有游标的出现,他的用处主要有: 定位到结果集中的某一行. 对当前位置的数据进行读写. 可以对结果集中的数据单独操作,而不是整行执行相同的操作. 是面向集合的数据库管理系统和面向行的程序设计之间的桥梁. 游标的分类 根据游标检测结果集变化的能力和消耗资源的情况不同,SQL

SQL SERVER 游标的使用

--基于查询声明游标 declare cur CURSOR FOR select id from OrderProducts where OrderCode =@OrderCode --select @OrderProductsId = id from OrderProducts where OrderCode [email protected] --打开游标 OPEN cur --读取下一个游标 FETCH NEXT FROM cur INTO @OrderProductsId --遍历游标记

学习使用MS SQL Server游标(CURSOR)

说实的,使用MS SQL Server这样久,游标一直没有使用过.以前实现相似的功能,都是使用WHILE循环加临时表来实现.刚才有参考网上示例练习写了一下.了解到游标概念与语法.下面代码示例中,先是宣告你在游标中需使用变量,也就是临时存储处理字段的数据.2. 宣告一个游标,并SELECT需要处理的数据集.3. 打开游标(#8行代码).4. 从游标中拿来FETCH NEXT 数据给变量赋值.5. 循环@@FETCH_STATUS = 0条件.6. 在循环块,可以处理第一笔的记录逻辑了.本示例中是P

sql server 游标的简单用法

sql server游标: --定义游标 declare cursor1 cursor for select ID,Name from A --打开游标 open cursor1 declare @id int declare @name varchar(50) declare @n int declare @i int=1 set @n=(select COUNT(1) from A) while(@i<@n) begin set @[email protected]+1 fetch next

SQL Server游标(转)

清晰地介绍了SQL游标,很好的学习资料. 转自 http://www.cnblogs.com/knowledgesea/p/3699851.html 什么是游标 结果集,结果集就是select查询之后返回的所有行数据的集合. 游标则是处理结果集的一种机制吧,它可以定位到结果集中的某一行,多数据进行读写,也可以移动游标定位到你所需要的行中进行操作数据. 一般复杂的存储过程,都会有游标的出现,他的用处主要有: 定位到结果集中的某一行. 对当前位置的数据进行读写. 可以对结果集中的数据单独操作,而不是

sql server 游标的知识

一:认识游标   游标是SQL Server的一种数据访问机制,它允许用户访问单独的数据行.用户可以对每一行进行单独的处理,从而降低系统开销和潜在的阻隔情况,用户也可以使用这些数据生成的SQL代码并立即执行或输出. 1.游标的概念  游标是一种处理数据的方法,主要用于存储过程,触发器和 T_SQL脚本中,它们使结果集的内容可用于其它T_SQL语句.在查看或处理结果集中向前或向后浏览数据的功能.类似与C语言中的指针,它可以指向结果集中的任意位置,当要对结果集进行逐条单独处理时,必须声明一个指向该结

SQL Server 游标使用

1.声明游标            DECLARE 游标名 CURSOR SELECT语句(注:此处一定是SELECT语句)        2.打开游标           OPEN 游标名        3.读取游标数据           Fetch [Next | Prior | First | Last | Absolute n | Relative n ]  From 游标名 INTO @name1,@name2...            WHILE(@@FETCH_STATUS =

SQL Server 游标的使用示例

?  简介 本文主要记录 MSSQL 中的游标使用示例,在有必要时方便借鉴查阅.游标一般定义在某段功能性的 SQL 语句中,或者存储过程中.之所以选择用它,是因为有时候无法使用简单的 SQL 语句满足我们需求,比如需要对结果集中的每一条数据,根据不同条件进行不同操作(CRUD),这时我们就可以使用游标来完成. 提示:来之 DBA 的杰作,哈哈~~ 1.   示例1: 本示例,用于初始化某新表的数据.使用游标遍历查询结果集,根据遍历的数据再插入另外两张表,SQL 代码如下: IF(OBJECT_I

SQL Server游标的使用【转】

游标是邪恶的! 在关系数据库中,我们对于查询的思考是面向集合的.而游标打破了这一规则,游标使得我们思考方式变为逐行进行.对于类C的开发人员来着,这样的思考方式会更加舒服. 正常面向集合的思维方式是: 而对于游标来说: 这也是为什么游标是邪恶的,它会使开发人员变懒,懒得去想用面向集合的查询方式实现某些功能. 同样的,在性能上,游标会吃更多的内存,减少可用的并发,占用宽带,锁定资源,当然还有更多的代码量…… 从游标对数据库的读取方式来说,不难看出游标为什么占用更多的资源,打个比方: 当你从ATM取钱