我们都知道在关系数据库中,都是面向集合进行查询的,而游标却是化整为零,是按行查询的,举个例子比如说之前那个壕买了99台苹果6,他可以一次性就买了99台,这正是我们平常使用SQL的方式,他也可以分成若干次买,这就是游标的方式,一次只查询一行。
-- 游标分为游标类型和游标变量,对于游标变量来说,游标变量支持两种方式赋值,定义时赋值和先定义后赋值,
--定义游标变量像定义其他局部变量一样,在游标前加”@”,注意,如果定义全局的游标,只支持定义时直接赋值,
--并且不能在游标名称前面加“@”,两种定义方式如下:
--DECLARE cursor_name CURSOR [ LOCAL | GLOBAL ]
-- [ FORWARD_ONLY | SCROLL ]
-- [ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]
-- [ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]
-- [ TYPE_WARNING ]
-- FOR select_statement
-- [ FOR UPDATE [ OF column_name [ ,...n ] ] ]
其中各参数的含义:
STATIC KEYSET DYNAMIC 和 FAST_FORWARD 四选一
这四个关键字是游标所在数据集所反应的表内数据和游标读取出的数据的关系
STATIC意味着,当游标被建立时,将会创建FOR后面的SELECT语句所包含数据集的副本存入tempdb数据库中,任何对于底层表内数据的更改不会影响到游标的内容.
DYNAMIC是和STATIC完全相反的选项,当底层数据库更改时,游标的内容也随之得到反映,在下一次fetch中,数据内容会随之改变
KEYSET可以理解为介于STATIC和DYNAMIC的折中方案。将游标所在结果集的唯一能确定每一行的主键存入tempdb,当结果集中任何行改变或者删除时,@@FETCH_STATUS会为-2,KEYSET无法探测新加入的数据
FAST_FORWARD可以理解成FORWARD_ONLY的优化版本.FORWARD_ONLY执行的是静态计划,而FAST_FORWARD是根据情况进行选择采用动态计划还是静态计划,大多数情况下FAST_FORWARD要比FORWARD_ONLY性能略好.
READ_ONLY SCROLL_LOCKS OPTIMISTIC 三选一
READ_ONLY意味着声明的游标只能读取数据,游标不能做任何更新操作
SCROLL_LOCKS是另一种极端,将读入游标的所有数据进行锁定,防止其他程序进行更改,以确保更新的绝对成功
--定义后直接赋值全局游标,在批处理结束之后依然存在
--默认和FORWARD_ONLY只支持FETCH NEXT 选项;SCROLL 支持向任何方向移动
Declare goods_CursorG CURSOR global SCROLL FOR
Select GoodsId from T_Goods
PS:FETCH的一些参数:
-- 游标分为游标类型和游标变量,对于游标变量来说,游标变量支持两种方式赋值,定义时赋值和先定义后赋值,
--定义游标变量像定义其他局部变量一样,在游标前加”@”,注意,如果定义全局的游标,只支持定义时直接赋值,
--并且不能在游标名称前面加“@”,两种定义方式如下:
--DECLARE cursor_name CURSOR [ LOCAL | GLOBAL ]
-- [ FORWARD_ONLY | SCROLL ]
-- [ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]
-- [ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]
-- [ TYPE_WARNING ]
-- FOR select_statement
-- [ FOR UPDATE [ OF column_name [ ,...n ] ] ]
其中各参数的含义:
STATIC KEYSET DYNAMIC 和 FAST_FORWARD 四选一
这四个关键字是游标所在数据集所反应的表内数据和游标读取出的数据的关系
STATIC意味着,当游标被建立时,将会创建FOR后面的SELECT语句所包含数据集的副本存入tempdb数据库中,任何对于底层表内数据的更改不会影响到游标的内容.
DYNAMIC是和STATIC完全相反的选项,当底层数据库更改时,游标的内容也随之得到反映,在下一次fetch中,数据内容会随之改变
KEYSET可以理解为介于STATIC和DYNAMIC的折中方案。将游标所在结果集的唯一能确定每一行的主键存入tempdb,当结果集中任何行改变或者删除时,@@FETCH_STATUS会为-2,KEYSET无法探测新加入的数据
FAST_FORWARD可以理解成FORWARD_ONLY的优化版本.FORWARD_ONLY执行的是静态计划,而FAST_FORWARD是根据情况进行选择采用动态计划还是静态计划,大多数情况下FAST_FORWARD要比FORWARD_ONLY性能略好.
READ_ONLY SCROLL_LOCKS OPTIMISTIC 三选一
READ_ONLY意味着声明的游标只能读取数据,游标不能做任何更新操作
SCROLL_LOCKS是另一种极端,将读入游标的所有数据进行锁定,防止其他程序进行更改,以确保更新的绝对成功
OPTIMISTIC是相对比较好的一个选择,OPTIMISTIC不锁定任何数据,当需要在游标中更新数据时,如果底层表数据更新,则游标内数据更新不成功,如果,底层表数据未更新,则游标内表数据可以更新
--定义后直接赋值全局游标,在批处理结束之后依然存在
--默认和FORWARD_ONLY只支持FETCH NEXT 选项;SCROLL 支持向任何方向移动
Declare goods_CursorG CURSOR global SCROLL FOR
Select GoodsId from T_Goods
--先定义后赋值,局部游标,在批处理结束后被隐式释放,无法再让其他批处理中调用
--Declare @goods_CursorT CURSOR
--Set @goods_CursorT= CURSOR FOR
--Select * from T_Goods
GO
--OPEN goods_CursorT
OPEN goods_CursorG
--FETCH LAST FROM goods_CursorT
--FETCH LAST FROM goods_CursorG
--取下一行
Declare @nextRow VARCHAR(200)
FETCH NEXT FROM goods_CursorG INTO @nextRow
PRINT @nextRow
--取最后一行
Declare @lastRow VARCHAR(200)
FETCH LAST FROM goods_CursorG INTO @lastRow
PRINT @lastRow
--取第一行
Declare @firstRow VARCHAR(200)
FETCH FIRST FROM goods_CursorG INTO @firstRow
PRINT @firstRow
--取上一行
Declare @preRow VARCHAR(200)
FETCH PRIOR FROM goods_CursorG INTO @preRow
PRINT @preRow
--取第三行
Declare @thirdRow VARCHAR(200)
FETCH ABSOLUTE 3 FROM goods_CursorG INTO @thirdRow
PRINT @thirdRow
--取相对当前来说上一行
Declare @relativeRow VARCHAR(200)
FETCH RELATIVE -1 FROM goods_CursorG INTO @relativeRow
PRINT @relativeRow
--关闭游标
--CLOSE goods_CursorG
--释放游标
--DEALLOCATE goods_CursorG
游标经常会和全局变量@@FETCH_STATUS与WHILE循环来共同使用,以达到遍历游标所在数据集的目的
Declare good_CursorG CURSOR global SCROLL FOR
Select GoodsId,GoodsType from T_Goods
Open good_CursorG
Declare @id nvarchar(200)
Declare @type nvarchar(200)
While @@FETCH_STATUS=0
Begin
Print @id
Print @type
FETCH NEXT FROM good_CursorG INTO @id,@type
End
CLOSE good_CursorG
DEALLOCATE good_CursorG
PS:FETCH的一些参数: