背景
:
定义游标的时候
,
如果不指定
STATIC
关键字的时候
,
则默认定义的游标是动态
(
DYNAMIC
)
的
动态
(
DYNAMIC
)
游标会反映在滚动游标时对结果集内的各行所做的所有数据更改。行的数据值、顺序和成员身份在每次提取时都会更改。动态游标不支持
ABSOLUTE
提取选项。
因为动态游标会消耗资源去检查基础表的更新
,
所以对于复杂的查询
,
且不需要反映基础表更新情况的游标处理中
,
将游标定义为静态的。另外,还有一种
KEYSET
类型的游标,它的行为介于动态和静态游标之间。
在笔者遇到的一个案例中
,
使用动态游标的处理会花费分钟
,
而改为静态游标后
,
处理时间只需要
1
秒钟
,
效率的差异非常明显
另外
,
在使用
DYNAMIC
游标的时候
,
必须注意“行的数据值、顺序和成员身份在每次提取时都会更改”的问题。
下面是一个看似正常
,
但实际执行会造成死循环的示例
SET
NOCOUNT ON
--
建立测试环境
DECLARE
@tb TABLE(
id int
PRIMARY KEY)
INSERT
@tb(
id)
SELECT
id = 1 UNION ALL
SELECT
id = 2
--
游标处理
DECLARE
tb CURSOR LOCAL FAST_FORWARD
FOR
SELECT
id FROM @tb
DECLARE
@id int
OPEN
tb
FETCH
tb INTO @id
WHILE
@@FETCH_STATUS = 0
BEGIN
PRINT @id
UPDATE @tb SET
id = id + 2
WHERE id = @id
FETCH tb INTO @id
END
CLOSE
tb
DEALLOCATE
tb