首页 新闻 会员 周边

动态游标的问题

0
悬赏园豆:50 [待解决问题]

如下边的例子

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Test](
[ID] [int] NOT NULL) ON [PRIMARY]

GO


INSERT INTO Test VALUES(1)
GO

DECLARE C$Cursor Cursor LOCAL FAST_FORWARD
FOR
SELECT ID From Test Where ID < 10

DECLARE @id INT

OPEN C$Cursor
Fetch C$Cursor INTO @id

WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE Test SET ID = ID + 1 WHERE id = @id
Fetch C$Cursor INTO @id
END

CLOSE C$Cursor
DEALLOCATE C$Cursor

按照MSDN的说明,如果不指定的话,默认游标应该是动态的游标,那么我更新数据后应该反映在游标中,所以最后结果应该是10,但是执行结果确是2,为什么?

Silade的主页 Silade | 初学一级 | 园豆:150
提问于:2012-02-02 23:55
< >
分享
所有回答(1)
0

当然是2了你游标提取的数据只有一条,然后这一条数据的ID为1,你将ID的字段加1后更新,当然是二了,那个10是你的筛选条件而已,并不是你要循环多少次。

az235 | 园豆:8483 (大侠五级) | 2012-02-03 08:35

如果是动态的话,它的更新应该反映到游标里,这样就能一直读取到刚刚更新数据,直到数据变更10不再满足条件。这是我理解。

支持(0) 反对(0) Silade | 园豆:150 (初学一级) | 2012-02-04 15:06

@Silade: 因为你的数据只有一条,游标提取完毕之后,游标就结束了,sql语句也有个执行的顺序,你放在前面 就是指执行一次,你放在循环里面就是多次。搞明白顺序

支持(0) 反对(0) az235 | 园豆:8483 (大侠五级) | 2012-02-06 13:02

@az235: 那我请问,下边的执行为啥是10

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Test](
 [ID] [int] NOT NULL,
 CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED ([ID] ASC)) ON [PRIMARY]

GO


INSERT INTO Test VALUES(1)
GO

DECLARE C$Cursor Cursor
FOR
SELECT ID From Test Where ID < 10

DECLARE @id INT

OPEN C$Cursor
Fetch  C$Cursor INTO @id

WHILE @@FETCH_STATUS = 0
BEGIN
 UPDATE Test SET ID = ID + 1 WHERE id = @id
 Fetch  C$Cursor INTO @id
END

CLOSE C$Cursor
DEALLOCATE C$Cursor

支持(0) 反对(0) Silade | 园豆:150 (初学一级) | 2012-02-06 23:29

@Silade: 上面的我说错了点东西,没有注意到你用了这几个关键字 Local FAST_FORWARD STATIC,你自己写的为静态游标,而下面的为动态游标,静态游标是以游标打开时刻的当时状态显示结果集的游标。静态游标在游标打开时不反映对基础数据进行的更新、删除或插入。有时称它们为快照游标。动态游标是可以在游标打开时反映对基础数据进行的修改的游标。用户所做的更新、删除和插入在动态游标中加以反映。

为我上面的错误道歉,谢谢。

支持(0) 反对(0) az235 | 园豆:8483 (大侠五级) | 2012-02-07 08:50

@az235: 我的第一个例子也没有STATIC 关键字,而且FAST_FORWARD 也不能与STATIC 同时存在,所以两个游标都是动态游标。

支持(0) 反对(0) Silade | 园豆:150 (初学一级) | 2012-02-07 23:26

@Silade: FAST_FORWARD 与Static不是互斥的参见这里http://shikonglaike.iteye.com/blog/1001161 

支持(0) 反对(0) az235 | 园豆:8483 (大侠五级) | 2012-02-08 09:47

@az235: 

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Test](
[ID] [int] NOT NULL) ON [PRIMARY]

GO


INSERT INTO Test VALUES(1)
GO

DECLARE C$Cursor Cursor FAST_FORWARD STATIC
FOR
SELECT ID From Test Where ID < 10

DECLARE @id INT

OPEN C$Cursor
Fetch C$Cursor INTO @id

WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE Test SET ID = ID + 1 WHERE id = @id
Fetch C$Cursor INTO @id
END

CLOSE C$Cursor
DEALLOCATE C$Cursor

以上代码会报错。

支持(0) 反对(0) Silade | 园豆:150 (初学一级) | 2012-02-08 23:15
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册