简析一下SQL Server里面Fast_Forword 和 SRROLL 的区别
这次简单说说游标的分类。
先看看通常游标的语法
DECLARE cursor_name CURSOR
[ LOCAL :局部游标,仅在当前会话有效
| GLOBAL : 全局游标,全局有效,可以
]
[ FORWARD_ONLY :只能向前游标,读取游标时只能使用 Next 谓词
| SCROLL :滚动游标,FIRST、LAST、PRIOR、NEXT、RELATIVE、ABSOLUTE 都可以使用
]
[ STATIC :定义一个游标,以创建将由该游标使用的数据的临时复本。对游标的所有请求都从 tempdb 中的这一临时表中得到应答;
| KEYSET :对基表中的非键值所做的更改(由游标所有者更改或由其他用户提交)可以在用户滚动游标时看到。其他用户执行的插入是不可见的(不能通过 Transact-SQL 服务器游标执行插入)。如果删除某一行,则在尝试提取该行时返回值为 -2 的 @@FETCH_STATUS。
| DYNAMIC :定义一个游标,以反映在滚动游标时对结果集内的各行所做的所有数据更改。行的数据值、顺序和成员身份在每次提取时都会更改。动态游标不支持 ABSOLUTE 提取选项
| FAST_FORWARD :指定启用了性能优化的 FORWARD_ONLY、READ_ONLY 游标。如果指定了 SCROLL 或 FOR_UPDATE,则不能也指定 FAST_FORWARD
]
[ READ_ONLY :只读游标,不能对游标内容进行更改,不能使用 where current of 语句
| SCROLL_LOCKS :指定通过游标进行的定位更新或删除一定会成功。将行读入游标时 SQL Server 将锁定这些行,以确保随后可对它们进行修改。
| OPTIMISTIC :指定如果行自读入游标以来已得到更新,则通过游标进行的定位更新或定位删除不成功。当将行读入游标时,SQL Server 不锁定行
]
[ TYPE_WARNING ]
FOR select_statement
[ FOR UPDATE [ OF column_name [ ,...n ] ] :制定那些列可以进行更新,如果不填,则默认全部可以更新
] 好了,抛完书包之后,现在问题来了,本人尽量图文并茂的描述每种类型的特点吧……_(:з」∠)_ --------------------------------------------------------------我是分割线-----------------------------------------------------------------------------------------------------------------------------------------------
测试表的结构
CREATE TABLE [dbo].[Employee]
(
[ID] [int] NOT NULL IDENTITY(1, 1) primary key,
[NAME] [nvarchar] (50) NULL,
[Name2] [varchar] (50) NULL
) ON [PRIMARY]
GO
FORWARD_ONLY 和 SCROLL
这两者在用的过程中还是比较好区别。一个只能前进,一个可以前滚翻后滚翻什么的。
先看看
FORWARD_ONLY
DECLARE CR_CURSOR CURSOR FAST_FORWARD --这个游标,是一个只读游标而已哦~
FOR
SELECT ID ,
NAME
FROM dbo.Employee
WHERE ID >= 24 DECLARE @ID INT ,
@Name NVARCHAR(50)
OPEN CR_CURSOR
FETCH NEXT FROM CR_CURSOR INTO @ID, @Name
WHILE @@FETCH_STATUS = 0
BEGIN
--UPDATE dbo.Employee SET Name2 = @Name WHERE CURRENT OF CR_CURSOR 因为是只读游标,所以是不允许修改游标本身内容
UPDATE dbo.Employee
SET Name2 = @Name
WHERE ID = @ID
FETCH NEXT FROM CR_CURSOR INTO @ID, @Name
END CLOSE CR_CURSOR
DEALLOCATE CR_CURSOR
然后我们看看执行计划,这个就跟普通的即时查询时没有任何区别的,所以我猜测,假如在游标读取过程中,数据发生了变化,是可以获取出来的。下面我来验证一下
1、在读取之前,我先温柔的删除Employee 表里面,ID = 25的记录
DELETE FROM dbo.Employee WHERE ID = 25
2、然后在读取游标里面开启单步调试,读到ID = 24的节点
3、然后在读下一个游标之前,我添加了一条数据
SET IDENTITY_INSERT Employee ON
INSERT INTO dbo.Employee
(ID,NAME )
VALUES ( 25,N'我是插进来的小三')
SET IDENTITY_INSERT Employee OFF
然后继续F10前进 ~咦~~25出来了野~
证明了,FORWARD_ONLY 这货是在游标向下滚动的时候即使获取数据的。所以能捕捉到新插入或删除的数据。 大致是这样纸了,下面在看看
SCROLL
DECLARE CR_CURSOR CURSOR SCROLL --代码基本一致,只是换成了 SCROLL
FOR
SELECT ID ,
NAME
FROM dbo.Employee
WHERE ID >= 24 DECLARE @ID INT ,
@Name NVARCHAR(50)
OPEN CR_CURSOR
FETCH NEXT FROM CR_CURSOR INTO @ID, @Name
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE dbo.Employee SET Name2 = @Name WHERE CURRENT OF CR_CURSOR --这句现在可以执行了
FETCH NEXT FROM CR_CURSOR INTO @ID, @Name
END CLOSE CR_CURSOR
DEALLOCATE CR_CURSOR
惯例先看看这个执行计划吧~
可以看到有一个查询过程要把数据插入到 CWT_PrimaryKey 的临时表里面。那我猜想,如果在游标读取途中,外部有数据的增加,是获取不到的了,那如果更新和删除会怎么样呢?实验一下
1、在读取之前,我还是先温柔的删除Employee 表里面,ID = 25的记录
DELETE FROM dbo.Employee WHERE ID = 25
2、然后在读取游标里面开启单步调试,读到ID = 24的节点
3、然后在读下一个游标之前,我添加了一条数据
SET IDENTITY_INSERT Employee ON
INSERT INTO dbo.Employee
(ID,NAME )
VALUES ( 25,N'我是插进来的小三')
SET IDENTITY_INSERT Employee OFF
然后F10……ID25没有粗线_(:з」∠)_直接到26去了
确实,外部新增了数据,是获取不到的。下面测一下修改和删除。
1、然后在读取游标里面开启单步调试,读到ID = 24的节点
2、修改ID是25的数据
UPDATE dbo.Employee SET NAME = '我是修改了的ID25哦' WHERE ID = 25
3、然后按F10继续走,是可以获取的哟~
删除呢?
重试一遍,在单步的过程中直接将 ID = 25的数据抹掉,然后就直接循环结束了~查了一下 @@Fetch_Status = -2 提取数据失败,当然啦……数据都被删除了。顺带一提,如果继续往下取,还是可以取到下一条数据的哟~
……图就不截了。。。
然后在继续试下各种方式,再进行补充
简析一下SQL Server里面Fast_Forword 和 SRROLL 的区别的更多相关文章
- SQL Server 中 EXEC 与 SP_EXECUTESQL 的区别
SQL Server 中 EXEC 与 SP_EXECUTESQL 的区别 MSSQL为我们提供了两种动态执行SQL语句的命令,分别是 EXEC 和 SP_EXECUTESQL ,我们先来看一下两种方 ...
- SQL Server 表变量和临时表的区别
SQL Server 表变量和临时表的区别 一.表变量 表变量在SQL Server 2000中首次被引入.表变量的具体定义包括列定义,列名,数据类型和约束.而在表变量中可以使用的约束包括主键约束,唯 ...
- SQL Server中SCAN 和SEEK的区别
SQL Server中SCAN 和SEEK的区别 SQL SERVER使用扫描(scan)和查找(seek)这两种算法从数据表和索引中读取数据.这两种算法构成了查询的基础,几乎无处不在.Scan会扫描 ...
- [转]SQL SERVER中openrowset与opendatasource的区别
本文转自:http://blog.sina.com.cn/s/blog_6399df820102vyy8.html SQL SERVER中openrowset与opendatasource的区别: o ...
- SQL SERVER 中的smalldatetime和datetime区别
原文:SQL SERVER 中的smalldatetime和datetime区别 smalldatetime不能到秒. 不過它占的空間小.(4位) datetime(8位) 而且兩者的時間範圍不一樣. ...
- 小记sql server临时表与表变量的区别
临时表与表变量都可以起到“临时”的作用,那么两者主要的区别是什么呢? 这里不讨论创建方式,以及全局临时表.会话临时表这些,主要记录一下个人对两者的主要区别以及适用情况的看法,有什么不对或补充的地方,欢 ...
- [转]SQL Server 表变量和临时表的区别
一.表变量 表变量在SQL Server 2000中首次被引入.表变量的具体定义包括列定义,列名,数据类型和约束.而在表变量中可以使用的约束包括主键约束,唯一约束,NULL约束和CHECK约束(外键约 ...
- SQL Server中Text和varchar(max) 区别
SQL Server 2005之后版本:请使用 varchar(max).nvarchar(max) 和 varbinary(max) 数据类型,而不要使用 text.ntext 和 image 数据 ...
- SQL SERVER 聚集索引 非聚集索引 区别
转自http://blog.csdn.net/single_wolf_wolf/article/details/52915862 一.理解索引的结构 索引在数据库中的作用类似于目录在书籍中的作用,用来 ...
随机推荐
- java 四舍五入保留小数
// 方式一: double f = 3.1516; BigDecimal b = new BigDecimal(f); double f1 = b.setScale(2, BigDecimal.RO ...
- java servlet上传centos服务器
前面一篇随笔说了Centos上架设javaWeb运行环境的方法,这篇主要讲打包上传服务器. 一.数据库连接文件.propeties 为了数据库安全,mysql3306端口访问我做了ip访问限制,由于m ...
- 【转】Nginx区分PC或手机访问不同网站
原文链接:http://www.nginx.cn/784.html 近几年来,随着手机和pad的普及,越来越多的用户选择使用移动客户端访问网站,而为了获取更好的用户体验,就需要针对不同的设备显示出最合 ...
- 基于 jQuery 实现的精致作品集图片导航效果
今天,我们要用 jQuery 来创建一个作品集图像的导航模板.我们的想法是,以分组的方式显示一组作品集,并通过二维的方式(水平/垂直)来浏览.任一箭头或当前图像下方的小盒子可以作为导航使用. 在线演示 ...
- JS高程2.在HTML中使用Javascript(1)
1.使用<script>元素向HTML页面中插入Javascript HTML4.01中<script>标签有6个属性: (1)async:可选.表示立即下载脚本,不影响页面中 ...
- [deviceone开发]-企业OA项目开源分享
一.简介 是一个真实的企业OA项目改造的开源项目,几乎涵盖了所有常用的组件,包括环信实现在线聊天等功能,类似微信的朋友圈功能,自定义的智能搜索等,而且这个是真实的通过Http链接后台web服务,里面很 ...
- Nodejs学习笔记(四)--- 与MySQL交互(felixge/node-mysql)
目录 简介和安装 测试MySQL 认识一下Connection Options MYSQL CURD 插入 更新 查询 删除 Nodejs 调用带out参数的存储过程,并得到out参数返回值 结束数据 ...
- Swift安装
Server1 .Update sudo apt-get update sudo apt-get upgrade . sudo apt-get install bridge-utils .IP 3.1 ...
- MyEclipse 2015 CI 14发布(附下载)
支持Web和Node.jsd的JavaScript Debugger调试器,新版本功能更加强大,在MyEclipse调试web应用程序变得更方便.调试器支持断点.变量和表达式. 类的动态预加载用Hot ...
- FIM2010同步用户
在需要进行同步的来源MA进行同步 在需要进行导入的来源进行导入