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