一:什么是游标?
游标 也就是 游 结果集,是为了对结果集更方便的处理的一个机制。也就是游标是为了对一个结果集的内容处理,去定位数据去操作它。
白话:就是想要操作数据集中的某一行。
二:为什么要用游标?
因为有时候用一些平常的查询之类的没有办法实现。
三:怎么使用游标?
定义:
DECLARE 游标名字 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 ] ] ]
参数说明:
- cursor_name:游标名称。
- Local:作用域为局部,只在定义它的批处理,存储过程或触发器中有效。
- Global:作用域为全局,由连接执行的任何存储过程或批处理中,都可以引用该游标。
- [Local | Global]:默认为local。
- Forward_Only:指定游标智能从第一行滚到最后一行。Fetch Next是唯一支持的提取选项。如果在指定Forward_Only是不指定Static、KeySet、Dynamic关键字,默认为Dynamic游标。如果Forward_Only和Scroll没有指定,Static、KeySet、Dynamic游标默认为Scroll,Fast_Forward默认为Forward_Only
- Static:静态游标
- KeySet:键集游标
- Dynamic:动态游标,不支持Absolute提取选项
- Fast_Forward:指定启用了性能优化的Forward_Only、Read_Only游标。如果指定啦Scroll或For_Update,就不能指定他啦。
- Read_Only:不能通过游标对数据进行删改。
- Scroll_Locks:将行读入游标是,锁定这些行,确保删除或更新一定会成功。如果指定啦Fast_Forward或Static,就不能指定他啦。
- Optimistic:指定如果行自读入游标以来已得到更新,则通过游标进行的定位更新或定位删除不成功。当将行读入游标时,sqlserver不锁定行,它改用timestamp列值的比较结果来确定行读入游标后是否发生了修改,如果表不行timestamp列,它改用校验和值进行确定。如果已修改改行,则尝试进行的定位更新或删除将失败。如果指定啦Fast_Forward,则不能指定他。
- Type_Warning:指定将游标从所请求的类型隐式转换为另一种类型时向客户端发送警告信息。
- For Update[of column_name ,....] :定义游标中可更新的列。
定义完然后打开 然后就是 操作了
declare cursor_test1 cursor scroll for select TourOrderId from tb1 定义游标也就是定义需要的结果集
open cursor_test1 打开游标 也就是打开结果集
fetch next from cursor_test1 into @变量 然后从结果集中查询某一行的数据 也可以into到一个变量 select @变量
close cursor_test1 关闭游标
deallocate cursor_test1 删除游标
查找规则:
参数说明:
- Frist:结果集的第一行
- Prior:当前位置的上一行
- Next:当前位置的下一行
- Last:最后一行
- Absoute n:从游标的第一行开始数,第n行。
- Relative n:从当前位置数,第n行。
- Into @variable_name[,...] : 将提取到的数据存放到变量中
除了查询结果集的话 也可以更新内容
fetch First from cursor_test1
while @@fetch_status=0 --提取成功,进行下一条数据的提取操作
begin
if @TourOrderId =122182
begin
Update tb1 Set UserId='123' Where Current of cursor_test1 --修改当前行
end
if @TourOrderId =154074
begin
Delete tb1 Where Current of cursor_test1 --删除当前行
end
fetch next from cursor_test1 into @变量 --移动游标
end
游标状态有三种
通过检测全局变量@@Fetch_Status的值,获得提取状态信息,该状态用于判断Fetch语句返回数据的有效性。当执行一条Fetch语句之后,@@Fetch_Status可能出现3种值:0,Fetch语句成功。-1:Fetch语句失败或行不在结果集中。-2:提取的行不存在。
对于游标一些优化建议
如果能不用游标,尽量不要使用游标
用完用完之后一定要关闭和释放
尽量不要在大量数据上定义游标
尽量不要使用游标上更新数据
尽量不要使用insensitive, static和keyset这些参数定义游标
如果可以,尽量使用FAST_FORWARD关键字定义游标
如果只对数据进行读取,当读取时只用到FETCH NEXT选项,则最好使用FORWARD_ONLY参数
使用游标经常会比使用面向集合的方法慢2-3倍,当游标定义在大数据量时,这个比例还会增加。如果可能,尽量使用while,子查询,临时表,函数,表变量等来替代游标,记住,游标永远只是你最后无奈之下的选择,而不是首选