SQL Server游标有什么优缺点,具体如何使用
Admin 2022-08-02 群英技术资讯 560 次浏览
游标是面向行的,它会使开发人员变懒,懒得去想用面向集合的查询方式实现某些功能。
在性能上,游标会吃更多的内存,减少可用的并发,占用带宽,锁定资源,当然还有更多的代码量。用一个比喻来说明为什么游标会占用更多的资源。当你从ATM机取款的时候,是一次取1000的效率更高呢,还是10次100呢?
游标是非常邪恶的一种存在,使用游标经常会比使用面向集合的方法慢2-3倍,当游标定义在大数据量时,这个比例还会增加。如果可能,尽量使用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;
参数解释:
如果不指定游标作用域,默认作用域为GLOBAL。
--全局游标,跨GLOBAL declare test_Cursor cursor global for select * from Person; --局部游标,跨LOCAL declare test_Cursor2 cursor local for select * from Person; go --用GO结束上面的作用域 open test_Cursor; open test_Cursor2; --此行代码报错,报游标不存在,因此可以理解局部游标不跨批处理,批处理结束后,将被隐式释放,无法在其他批处理中调用
--不加参数,默认为Forward_Only declare test_Cursor cursor for select * from Person; --加Forward_Only declare test_Cursor2 cursor forward_only for select * from Person; --加SCROLL declare 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; --正确执行
这四个关键字是游标所在数据集所反映的表数据和游标读取出数据的关系
当定义完游标后,游标需要打开后使用,只需一行代码便可打开游标:
OPEN test_Cursor
注意,当全局游标和局部游标变量重名时,默认会打开局部变量游标。
游标的使用分为两部分,一部分是操作游标在数据集内的指向,另一部分是将游标所指向的行的部分或全部内容进行操作。
支持6种移动导航,分别为:
例如:
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种值:
游标总记录数 @@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;
游标修改当前行数据语法:
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
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
这篇文章介绍了SQL Server中T-SQL标识符与无排序生成序号的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
本文讲的是SQLserver数据库创建新用户方法以及赋予此用户特定权限的方法,非常的简单实用,有需要的小伙伴可以参考下
今天遇到了关于Sql Server最大连接数(Max Pool Size)的问题,后来通过查找一些资料解决了,所以想着总结下关于SQL Server最大连接数的内容,所以这篇文章主要介绍了SQL设置SQL Server最大连接数与查询语句,有需要的朋友们可以参考借鉴。
查看MSSQL数据库每个表占用的空间大小 sp_spaceused显示行数、保留的磁盘空间以及当前数据库中的表所使用的磁盘空间,或显示由整个数据库保留和使用的磁盘空间。语法sp_spaceused [[@objname =] 'objnam
一些刚接触SQL server的新手,对于怎么解决session阻塞不是很清楚,当然方法很多,下文是个人经验,感兴趣的朋友可以参考,希望本文对大家理解和解决session阻塞有帮助。
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008