千家信息网

SQL Server中的游标怎么定义和使用

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,这篇文章主要介绍"SQL Server中的游标怎么定义和使用"的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇"SQL Server中的游标怎么定义和使用"文章能帮
千家信息网最后更新 2026年10月31日SQL Server中的游标怎么定义和使用

这篇文章主要介绍"SQL Server中的游标怎么定义和使用"的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇"SQL Server中的游标怎么定义和使用"文章能帮助大家解决问题。

游标是面向行的,它会使开发人员变懒,懒得去想用面向集合的查询方式实现某些功能。

在性能上,游标会吃更多的内存,减少可用的并发,占用带宽,锁定资源,当然还有更多的代码量。用一个比喻来说明为什么游标会占用更多的资源。当你从ATM机取款的时候,是一次取1000的效率更高呢,还是10次100呢?

游标是非常邪恶的一种存在,使用游标经常会比使用面向集合的方法慢2-3倍,当游标定义在大数据量时,这个比例还会增加。如果可能,尽量使用while,子查询,临时表,函数,表变量等来替代游标,记住,游标永远只是你最后无奈之下的选择,而不是首选。

既然游标那么多缺点,为什么要学习游标呢?

  • 现存系统有一些游标,我们查询必须通过游标来实现。

  • 作用一个备用方式,当使用while、子查询,临时表,表变量,自建函数或其他方式仍然无法实现某些查询的时候,可以使用游标实现。

游标的定义语法:

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 ] ] ][;]

一、定义游标

在T-SQL中,定义一个游标可以使非常简单,也可以相对复杂,这主要取决于游标的参数。而游标的参数设置取决于你对游标原理的了解程度。
游标其实可以理解成一个定义在特定数据集上的指针,我们可以控制这个指针遍历数据集,或者仅仅是指向特定的行,所以游标是定义在以SELECT开始的数据集上的。

游标分为游标类型和游标变量。

游标变量支持两种方式赋值,定义时赋值和先定义后赋值,定义游标变量像定义其他局部变量一样,在游标前加"@"。

注意,如果定义全局的游标,只支持定义时直接赋值,并且不能在游标名称前面加"@"。

两种定义方式如下:

--定义后直接赋值declare test_Cursor cursor for    select * from Person;--先定义后赋值declare @TEST_Cursor2 cursor;set @TEST_Cursor2 = cursor for    select * from Person;

参数解释:

1、LOCAL和GLOBAL二选一

如果不指定游标作用域,默认作用域为GLOBAL。

--全局游标,跨GLOBALdeclare test_Cursor cursor global for    select * from Person;--局部游标,跨LOCALdeclare test_Cursor2 cursor local for    select * from Person;go --用GO结束上面的作用域open test_Cursor;open test_Cursor2; --此行代码报错,报游标不存在,因此可以理解局部游标不跨批处理,批处理结束后,将被隐式释放,无法在其他批处理中调用

2、FORWARD_ONLY 和 SCROLL 二选一

  • FORWARD_ONLY意味着游标只能从数据集开始向数据集结束的方向读取,FETCH NEXT是唯一的选项。默认为Forward_Only。

  • SCROLL支持游标在定义的数据集中向任何方向,或任何位置移动。

--不加参数,默认为Forward_Onlydeclare test_Cursor cursor for    select * from Person;--加Forward_Onlydeclare test_Cursor2 cursor forward_only for    select * from Person;--加SCROLLdeclare test_Cursor3 cursor scroll for    select * from Person;open test_Cursor;open test_Cursor2;open test_Cursor3;fetch last from test_Cursor; --报错 fetch: 提取类型 last 不能与只进游标一起使用。fetch last from test_Cursor2; --报错 fetch: 提取类型 last 不能与只进游标一起使用。fetch last from test_Cursor3; --正确执行

3、游标的分类:STATIC、 KEYSET 、DYNAMIC 和 FAST_FORWARD 四选一

这四个关键字是游标所在数据集所反映的表数据和游标读取出数据的关系

  • STATIC:当游标被建立时,将会创建FOR后面的SELECT语句所包含数据集的副本存入tempdb数据库中,任何对于底层表内数据的更改不会影响到游标内容。

  • DYNAMIC:和STATIC完全相反的选项,当底层数据库更改时,游标的内容也会随之得到反映,在下一次fecth中,数据内容会随之更改。

  • KEYSET:可以理解为介于STATIC和DYNAMIC的折中方案,将游标所在结果集的唯一能确定每一行的主键存入tempdb,当结果集中任何行改变或者删除时,@@FETCH_STATUS会为-2,KEYSET无法探测新加入的数据。

  • FAST_FORWARD:可以理解为FORWARD_ONLY的优化版本。FORWARD_ONLY执行的是静态计划,而FAST_FORWARD是根据情况进行选择采用动态计划还是静态计划,大多数情况下FAST_FORWARD要比FORWARD_ONLY性能略好。

4、READ_ONLY 、 SCROLL_LOCKS 和 OPTIMISTIC 三选一

  • READ_ONLY:意味着声明的游标只能读取数据,游标不能做任何更新操作 。

  • SCROLL_LOCKS:是另一种极端,将读入游标的所有数据进行锁定,防止其他程序进行更改,以确保更新的绝对成功。

  • OPTIMISTIC:相对比较好的一个选择,OPTIMISTIC不锁定任何数据,当需要在游标中更新数据时,如果底层表数据更新,则游标内数据更新不成功,如果,底层表数据未更新,则游标内表数据可以更新。

5、For Update[of column_name ,....] :定义游标中可更新的列。

二、打开游标

当定义完游标后,游标需要打开后使用,只需一行代码便可打开游标:

OPEN test_Cursor

注意,当全局游标和局部游标变量重名时,默认会打开局部变量游标。

三、使用游标

1、利用游标提取数据

游标的使用分为两部分,一部分是操作游标在数据集内的指向,另一部分是将游标所指向的行的部分或全部内容进行操作。
支持6种移动导航,分别为:

  • 第一行(FIRST)

  • 最后一行(LAST)

  • 下一行(NEXT)

  • 上一行(PRIOR)

  • 直接跳到某行(ABSOLUTE(n))

  • 相对于目前跳几行(RELATIVE(n))

例如:

declare test_Cursor cursor scroll for    select name from Person;open test_Cursor;declare @c nvarchar(10);--取下一行fetch next from test_Cursor into @c;print @c;--取最后一行fetch last from test_Cursor into @c;print @c;--取第一行fetch first from test_Cursor into @c;print @c;--取上一行fetch prior from test_Cursor into @c;print @c;--取第三行fetch absolute 3 from test_Cursor into @c;print @c;--取相对目前来说上一行fetch relative -1 from test_Cursor into @c;print @c;

对于未指定SCROLL选项的游标来说(未指定,则是只进游标),只支持NEXT取值。

游标经常会和全局变量@@FETCH_STATUS与WHILE循环来共同使用,以达到遍历游标所在数据集的目的。

当执行一条Fetch语句之后,@@Fetch_Status可能出现3种值:

  • 0,Fetch语句成功。

  • -1:Fetch语句失败或行不在结果集中。

  • -2:提取的行不存在。

游标总记录数 @@CURSOR_ROWS

例如:

declare test_Cursor cursor fast_forward  for    select id, name from Person;open test_Cursor;declare @id int;declare @name nvarchar(10);fetch next from test_Cursor into @id, @name;while @@FETCH_STATUS = 0    begin        print @id;        print @name;        fetch next from test_Cursor into @id, @name;    end;close test_Cursor;deallocate test_Cursor;

2、利用游标更新删除数据

游标修改当前行数据语法:

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;close orderNum_03_cursor;deallocate orderNum_03_cursor;

四、关闭游标

在游标使用完之后,一定要记得关闭,只需要一行代码:CLOSE+游标名称

close  test_Cursor

五、释放游标

当游标不再需要被使用后,释放游标,只需要一行代码:DEALLOCATE+游标名称

deallocate test_Cursor

六、对于游标一些优化建议

  • 如果能不用游标,尽量不要使用游标

  • 用完之后一定要关闭和释放

  • 尽量不要在大量数据上定义游标

  • 尽量不要使用游标上更新数据

  • 尽量不要使用insensitive, static和keyset这些参数定义游标

  • 如果可以,尽量使用FAST_FORWARD关键字定义游标

  • 如果只对数据进行读取,当读取时只用到FETCH NEXT选项,则最好使用FORWARD_ONLY参数

关于"SQL Server中的游标怎么定义和使用"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注行业资讯频道,小编每天都会为大家更新不同的知识点。

游标 数据 一行 变量 更新 参数 查询 代码 内容 局部 方式 支持 成功 作用 全局 底层 更多 结果 语句 名称 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技公司 涨乐互联网科技 关于新基建和互联网科技 互联网科技与金融科技 互联网 的科技创新 唐信互联网科技 远拓互联网科技 上海亿帐通互联网科技 卓越科技互联网 招聘 互联网科技公司的市场部门 上海电发互联网科技有限公司 宁夏众和广鑫互联网科技有限公司 注册互联网科技公司经营范围大全 世界互联网领先科技成果获奖 卓翼科技产业互联网合作 恒生互联网科技业指数调整周期 为客找房互联网科技公司怎么样 陕西云淼互联网科技公司 互联网界的黑科技 同城互联网络科技 上海睿民互联网科技有限公司 新华互联网科技学院 美国互联网科技巨头监管 互联网科技金融 济南华为互联网科技产业总部基地 科技互联网的估值 健康食品互联网创新科技园项目 乌鲁木齐新华智原互联网科技学校 2021世界互联网领先科技成果发布 互联网科技大佬云集
0