美文网首页
sqlserver 游标-for

sqlserver 游标-for

作者: haidaozheng | 来源:发表于2019-05-24 16:05 被阅读0次

SQL Server游标

什么是游标

  • 结果集就是select查询之后返回的所有行数据的集合。
  • 游标是处理结果集的一种机制,它可以定位到结果集中的某一行

用处主要有:

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

游标的分类

  • 静态游标: 静态游标的结果集,在游标打开的时候建立在TempDB中,不论你在操作游标的时候,如何操作数据库,游标中的数据集都不会变。
  • 动态游标:这个则与静态游标相对,滚动游标时,动态游标反映结果集中的所有更改。结果集中的行数据值、顺序和成员在每次提取时都会变化。所有用户做的增删改语句通过游标均可见。
  • 只进游标:只进游标不支持滚动,只支持从头到尾顺序提取数据,数据库执行增删改,在提取时是可见的,但由于该游标只能进不能向后滚动,所以在行提取后对行做增删改是不可见的。
  • 键集驱动游标:打开键集驱动游标时,该有表中的各个成员身份和顺序是固定的。打开游标时,结果集这些行数据被一组唯一标识符标识,被标识的列做删改时,用户滚动游标是可见的,如果没被标识的列增该,则不可见,比如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_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

相关文章

  • Sqlserver存储过程如何写循环

    Sqlserver循环游标写法存储过程中循环的写法Sqlserver各种循环写法Sqlserver自带的while...

  • sqlserver 游标

    游标更新删除当前数据 1.声明游标 2.打开游标 3.声明游标提取数据所要存放的变量 4.定位游标到哪一行 5.关...

  • sqlserver 游标-for

    SQL Server游标 什么是游标 结果集就是select查询之后返回的所有行数据的集合。 游标是处理结果集的一...

  • SqlServer 利用游标批量操作数据

    SqlServer 利用游标批量更新数据 Intro 游标在有时候会很有用,在更新一部分不多的数据时,可以很方便的...

  • SqlServer使用For循环结合游标更新数据

    SqlServer使用For循环更新数据 Intro 有时候,可能会有一些需求更新一部分数据,需要遍历,但是又不想...

  • MongoDB之文档游标

    游标 查询操作返回的结果游标 游标的迭代与操作 db.collecton.find() 返回一个文档集合游标,在不...

  • Oracle 存储过程学习笔记

    1、存储过程简单实例 2.游标实现方式 显式游标实现方式(可多值) 隐式游标(可以实现查询多值) 带有参数的游标(...

  • sql server 游标

    定位到结果集中某一行 游标分类 静态游标(Static):在操作游标的时候,数据发生变化,游标中数据不变。 动态游...

  • 实验九 游标操作和自定义函数

    一.实验目的: 掌握游标的声明、游标打开、标数据的提取、游标的关闭和游标的释放 掌握标量值函数的定义与调用 掌握内...

  • sqlserver添加修改字段注释

    1、sqlserver添加表解释 举个例子 2、sqlserver添加字段解释 举个例子 3、sqlserver修...

网友评论

      本文标题:sqlserver 游标-for

      本文链接:https://www.haomeiwen.com/subject/dxpgzqtx.html