SQL Server 中游标的使用sql
1.游标是行读取,占用资源比sql多
2.游标的使用情景:
->现存的系统中使用的是游标,查询必须经过游标来实现
->用尽了while、子查询临时表、表变量、自定义函数以及其余方式仍然没法实现的时候,使用游标
3.T-SQL 中游标的生命周期由5部分组成
->定义游标:游标的定义遵循T-Sql的定义方法,赋值有两种方法,定义时赋值,和先定义后赋值,定义游标像定义其余局部变量同样前面要加@,注意若是是全局的游标,只支持定义时直接赋值,而且不能在游标前面加@
--定义时直接赋值
Declare test_Cursor Cursor For
select * from dbo.tb1
--先定义后赋值
Declare @test_Cursor2 Cursor
set @test_Cursor2=Cursor For
select * from dbo.tb2
Local和Global
Local意味着游标的生命周期只在批处理或函数或存储过程当中可见,而Global意味着游标对于特定的链接做为上下文,全局有效
--定义后直接赋值(全局)
Declare test_Cursor Cursor GLOBAL For
select * from dbo.tb1
--(局部)
Declare test_Cursor2 Cursor LOCAL For
select * from dbo.tb2
--用GO结束上面的做用域
GO
Open test_Cursor
Open test_Cursor2
报错:test_Cursor2不存在
注意:若是不指定游标做用域,默认为GLOBAL
Forward_Only和Scroll 二选一
Forward_Only意味着游标只能从数据集开始向着数据集结束的方向读取,惟一选项Fetch Next,而Scroll支持游标在定义数据集上向着任何方向或者任何位置移动
--不加参数默认为Forward_only
Declare test_Cursor Cursor For
select * from dbo.tb1
--加Forward_Only
Declare test_Cursor2 Cursor Forward_Only For
select * from dbo.tb1
--加Scroll
Declare test_Cursor3 Cursor Scroll For
select * from dbo.tb1
Open test_Cursor
Open test_Cursor2
Open test_Cursor3
Fetch Last from test_Cursor
Fetch Last from test_Cursor2
Fetch Last from test_Cursor3--读取最后一行
报错:只进游标test_Cursor不能与last一块儿使用,只进游标test_Cursor2不能与last一块儿使用
Static Keyset Dynamic 和 Fast_Forward四选一
这四个关键字是游标所在的数据集所反应的表内数据和游表读取出数据的关系。
Static:意味着,当游标被创建时候,将会建立For后面的select 语句所包含数据集的副本存入tempdb数据库中,任何对于底层表内数据的更改不会影响到游标的内容
Dynamic:是和Static彻底相反的选项,当底层数据库更改时,游标的内容也随之待到放映,在下一次fetch中,数据内容会随之改变
Keyset:能够理解为介于Static和Dynamic的折中方案。蒋友柏所在结果集的惟一能肯定每一行的主键存入tempdb,当结果中任何行改变或者删除时,@@FETCH_STATUS为-2,KEYSET没法探测新加入的数据
FAST_FORWAED能够理解成FORWARD_ONLY的优化版本,FORWARD_ONLY执行的是经计划,而FAST_FORWARD是根据状况进行选择采用动态计划仍是静态计划,大多数状况下FAST_FORWARD要比FORWARD_ONLY性能略好
READ_ONLY SCROLL_LOCKS OPTIMISTIC三选一
READ_ONLY:意味着声明的游标只能读取数据,游标不能作任何更新操做
SCROLL_LOCKS:是另外一种极端,将读入游标的全部数据进行锁定,防止其余程序进行更改,以确保更行的绝对成功
OPTIMISTIC:是相对比较好的一个选择,OPTIMISTIC不锁定任何数据,当须要在游标中更新数据时,若是底层数据更新,测游标内数据更新不成功,若是底层表数据为更新,则游标南日表数据能够更新
->打开游标:Open test_Cursor 注意,当全局游标和局部游标变量重名时,默认会打开局部变量游标
->使用游标:游标分为两部分,一部分是操做游标在数据集内的指向,另外一部分是将游标所直向的行的部分或所有内容进行操做
只支持6中移动选项,到第一行(FIRST),最后一行(LAST),下一行(NEXT),上一行(PRIOR),直接跳到某一行(ABSOLUTE(n)),相对于目前跳到几行(RELATIVE(n))
--必须指定SCROLL不然只支持next只进选项
DECLARE test_Cursor SCROLL FOR
select * from dbo.tb1
OPEN test_Cursor
DECLARE @c nvarchar(10)
--取下一行
Fetch next from test_Cursor into @c
print @c
--取最后一行
Fetch Last From test_Cursor into @c
print @c
--取第一行
Fetch first from test_Cursor into @c
print @c
--取上一行
fetch prior from test_Cursor into @c
print @c
--取第三行
fetch absolute 3 from test_Cursor into @c
print @c
--取相对目前来讲上一行(-2相对于目前来讲向上移动2行,2对目前来讲向下移动2行)
fetch relative -1 from test_Cursor into @c
print @c
对于为指定SCROLL的,只能用NEXT选项
游标常常回和全局变量@@FETCH_STATUS 与WHITLE循环来共同使用,历来遍历游标所在的数据集
Declare test_Cursor cursor scroll for
select id,name from dbo.tb1
Open test_Cursor
Declare @id int
Declare @name nvarchar(10)
while @@FETCH_STATUS=0
begin
print @id
print @name
Fetch next from test_Cursor into @id,@name
end
Close test_Cursor
Deallocate test_Cursor
->关闭游标: Close test_Cursor
->释放游标: Deallocate test_Cursor
注释1:
->游标的定义的复杂程度是和参数有关,而游标的参数设置是对游标的原理了解程度。
->游标的原理:游标是定义在特定数据集上的指针,咱们控制这个指针遍历数据集,或者仅仅是指向特定的行,因此游标是定义在以select开始的数据集上的。
注释2:
若是能不用游标,尽可能不要使用游标
用完用完以后必定要关闭和释放
尽可能不要在大量数据上定义游标
尽可能不要使用游标上更新数据
尽可能不要使用insensitive, static和keyset这些参数定义游标
若是能够,尽可能使用FAST_FORWARD关键字定义游标
若是只对数据进行读取,当读取时只用到FETCH NEXT选项,则最好使用FORWARD_ONLY参数数据库