简析一下SQL Server里面Fast_Forword 和 SRROLL 的区别

原文:简析一下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 提取数据失败,当然啦……数据都被删除了。顺带一提,如果继续往下取,还是可以取到下一条数据的哟~……图就不截了。。。

然后在继续试下各种方式,再进行补充
				
时间: 2024-09-10 20:43:01

简析一下SQL Server里面Fast_Forword 和 SRROLL 的区别的相关文章

简析基于SQL SERVER分页存储过程的演进

针对数据库数据在UI界面上的分页是老生常谈的问题了,网上很容易找到各种"通用存储过程"代码,而且有些还定制查询条件,看上去使用很方便.笔者打算通过本文也来简单谈一下基于SQL SERVER 2000的分页存储过程,同时谈谈SQL SERVER 2005下分页存储过程的演进. 在进行基于UI显示的数据分页时,常见的数据提取方式主要有两种.第一种是从数据库提取所有数据然后在系统应用程序层进行数据分页,显示当前页数据.第二种分页方式为从数据库取出需要显示的一页数据显示在UI界面上. 以下是笔

SQL Server 中 EXEC 与 SP_EXECUTESQL 的区别

原文:SQL Server 中 EXEC 与 SP_EXECUTESQL 的区别 MSSQL为我们提供了两种动态执行SQL语句的命令,分别是 EXEC 和 SP_EXECUTESQL ,我们先来看一下两种方式的用法. 先建立一个表,并添加一些数据来进行演示: CREATE TABLE t_student( Id INT NOT NULL, Name NVARCHAR (10) NULL, Age TINYINT NULL, School NVARCHAR(20) NULL, Class NVAR

SQL Server数据库和Oracle数据库的区别

区别|数据|数据库|oracle|sqlserver 多年来,在微软的支持者和甲骨文的支持者之间一直持续着一场旷日持久的唇枪舌战.这边说Oracle数据库有如此这般功能,那边又说SQL Server这些个那些个特性,各持己见.可是,这并不是关键所在.诚然,性能是评价数据库优劣的重要指标之一,能够帮您完成您需要它完成的任务当然要更胜一筹.但是,你知不知道这两家公司和他们各自产品的真正区别在哪里?而你又知不知道微软为什么能够有轻轻打个喷嚏就能震动整个业界的影响力呢? 答案很简单,两个字:信息.微软以

oracle和sql server取第一条记录的区别以及rownum详解

我们知道学生可能有重名的情况,那么当重名的时候假设只需要取得重名结果集中的第一条记录.   sql server:select top(1) num,Name from M_Student where name = 'xy'   Oracle:select num,Name from M_Student where name = 'xy' and rownum <= 1 对于rownum在oracle的使用的时候,有几点需要注意:   (1) rownum 对于等于某值的查询条件 如果希望找到学

SQL Server与Oracle并行访问的区别

设计优良.性能卓越的数据库引擎可以轻松地同时为成千上万的用户服务.而"底气不足"的数据库系统随着更多的用户同时访问系统将大大降低其性能.最糟糕的情况下甚至可能导致系统的崩溃. 中国.站.长站 当然,并行访问是任何数据库解决方案都最为重视的问题了,为了解决并行访问方面的问题各类数据库系统提出了各种各样的方案.SQL Server和Oracle两大DBMS也分别采用了不同的并行处理方法.它们之间的实质差别在哪里呢? Www.Chinaz.com 并行访问的问题     并行访问出现问题存在

SQL Server中clustered与nonclustered的区别

        CLUSTERED :聚集索引.非聚集索引:NONCLUSTERED.         clustered是物理上实现数据排序,并且同一个表里只能有一个clustered索引,而nonclustered是逻辑上的排序.         微软的SQL Server 支持两种类型的索引:clustered 索引和nonclustered索引.         Clustered索引在数据表中按照物理顺序存储数据.因为在表中只有一个物理顺序,所以在每个表中只能有一个clustered索

SQL Server 表变量和临时表的区别(详细补充篇)_MsSql

一.表变量 表变量在SQL Server 2000中首次被引入.表变量的具体定义包括列定义,列名,数据类型和约束.而在表变量中可以使用的约束包括主键约束,唯一约束,NULL约束和CHECK约束(外键约束不能在表变量中使用).定义表变量的语句是和正常使用Create Table定义表语句的子集.只是表变量通过DECLARE @local_variable语句进行定义. 表变量的特征: 1.表变量拥有特定作用域(在当前批处理语句中,但不在任何当前批处理语句调用的存储过程和函数中),表变量在批处理结束

在ACCESS和SQL Server下Like 日期类型查询区别_数据库其它

最近在用ACCESS数据库是遇到的问题总结: 一.在ACCESS中LIKE的用法 Access里like的通配符用法是这样: "?"表示任何单一字符: "*"表示零个或多个字符: "#"表示任何一个数字 所以应该是: select * from databasename where fieldname like '*XX*' 但在SQL SERVER 里是用%表示零个或多个字符 二.如何在ACCESS查询datetime类型字段的日期范围数据 如

SQL Server 表变量和临时表的区别(详细补充篇)

一.表变量 表变量在SQL Server 2000中首次被引入.表变量的具体定义包括列定义,列名,数据类型和约束.而在表变量中可以使用的约束包括主键约束,唯一约束,NULL约束和CHECK约束(外键约束不能在表变量中使用).定义表变量的语句是和正常使用Create Table定义表语句的子集.只是表变量通过DECLARE @local_variable语句进行定义. 表变量的特征: 1.表变量拥有特定作用域(在当前批处理语句中,但不在任何当前批处理语句调用的存储过程和函数中),表变量在批处理结束