当前位置:Gxlcms > 数据库问题 > 简析一下SQL Server里面Fast_Forword 和 SRROLL 的区别

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

时间:2021-07-01 10:21:17 帮助过:3人阅读

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 的区别

标签:

人气教程排行