对于sql来说查询的思维方式的面向集合
对于游标来说:思维方式是面向行的

性能上:游标会吃更多内存,减少可见的并发,锁定资源等

当穷尽了while循环,临时表,表变量,自建函数,或其他方式仍然无法实现某些查询的时候,可以考虑使用游标

游标的生命周期由5部分组成:

游标可以很简单,也可以很复杂,取决于游标的参数

游标可以理解为定义在数据集上的指针,可以控制这个指针遍历数据集,或者仅仅指向特定的行,所以游标是定义在以select开始的数据集上的

游标的定义:

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 ] ] ]
[;]

游标分为:游标类型和游标变量,
游标变量遵循T-sql变量的定义方法,支持两种方式赋值,定义时赋值和先定义后赋值
如果定义局部游标:在游标前加 @
如果定义全局的游标,只支持在定义的时候直接赋值,并且不能在游标名称前面加 @
例如:

--定义的全局游标,游标变量没有@,全局游标定义需要直接进行赋值
DECLARE cur_test CURSOR FOR
SELECT * FROM AuthToken AS at --定义的局部游标,需要使用@声明变量
DECLARE @cur_test2 CURSOR
--先声明变量,然后再进行赋值
SET @cur_test2 = CURSOR FOR
SELECT * FROM AuthToken AS at

游标的参数:
Local和global二选一

Local:意味着游标的生存周期只在批处理或者函数或者存储过程中可见,
Global:意味着游标对于特定连接作为上下文,全局内有效

全局游标:在批处理后依然有效,
局部游标:在批处理结束后被隐式释放,无法在其他批处理中调用

--定义的全局游标,游标变量没有@,全局游标定义需要直接进行赋值
DECLARE cur_test CURSOR GLOBAL FOR
SELECT * FROM AuthToken AS at DECLARE cur_test CURSOR LOCAL FOR
SELECT * FROM AuthToken AS at

如果不指定,默认为global

FORWARD_ONLY 和SCROLL二选一

forward_only:意味着游标只能从数据集开始向数据集结束的方向读取,Fetch next是唯一选项,
scroll支持游标在定义的数据集中向任何方向,或者任何位置移动

例如:

--不加参数,默认为 forward_only
DECLARE Test_Cursor CURSOR FOR
SELECT * FROM AuthToken AS at -- 加scroll参数,支持游标指针向数据集的任意方向移动,
DECLARE Test2_Cursor CURSOR SCROLL FOR
SELECT * FROM AuthToken AS at -- 加FORWARD_ONLY参数,支持游标指针 只能从 数据集开始方向向结束方向移动,
DECLARE Test3_Cursor CURSOR FORWARD_ONLY FOR
SELECT * FROM AuthToken AS at OPEN Test_Cursor
OPEN Test2_Cursor
OPEN Test3_Cursor --只支持从数据集开始方向向结束方向移动
FETCH NEXT FROM Test_Cursor
FETCH NEXT FROM Test3_Cursor
--SCROLL 支持向任意方向移动
FETCH NEXT FROM Test2_Cursor
FETCH LAST FROM Test2_Cursor

static,keyset, dynamic 和 fast_forward 四选一

这四个参数是游标所在数据集所反应的表内数据和游标读取出的数据的关系

static:意味着当游标被建立时,将会创建 for后面的 select语句所包含数据集的副本存入 tempdb数据库中,任何对于底层表内数据的更改都不会影响到游标的内容

dynamic:和static相反,当底层数据库表内内容更改时,游标的内容也随之改变,下一次 fetch中,数据内容会随之改变

keyset:是上面两种的折中方案:将游标所在结果集的唯一能确定每一行的主键存入tempdb,当结果集中任何行改变或者删除时,@@Fetch_status 会为 -2,keyset无法探测新加入的数据

fast_forward:是forward_only的优化版本,forward_only执行的是 静态计划,
而Fast_forward是根据情况进行选择采用动态计划还是静态计划,

Read_only ,Scroll_locks,Optimistic三选一
Read_only:意味着声明的游标只能读取数据,游标不能做任何更新操作
scroll_locks:将读入游标的所有数据进行锁定,防止其他程序进行更改,以确保更新的绝对成功

Optimistic:不锁定任何数据,当需要在游标中更新数据时,如果底层表数据更新,则游标内数据更新不成功,如果底层表数据未更新,则游标内表数据可以更新

打开游标:

当游标定义完,需要打开后才能使用
Open test_cursor

注意:当全局游标和局部游标变量重名时,默认会打开局部变量游标

3 使用游标:

游标的使用分为两部分:
一部分是操作游标在数据集内的指向,
一部分是将游标所指向的行的部分或全部内容进行操作

支持6种移动选项
到第一行:first
最后一行:last
下一行:next
上一行:prior
直接跳到某行:absolute(n)
相对于目前跳几行(relative(n))

对于未指定scroll选项的游标来说,只支持next取值

例如:

DEALLOCATE test_cursor
--定义一个全局游标,并且支持向任意方向移动
DECLARE test_cursor CURSOR SCROLL FOR
SELECT c.Nickname FROM dbo.Customer AS c
--定义好之后需要首先打开游标
OPEN test_cursor DECLARE @a NVARCHAR() --使用游标:取第一行数据到@a
FETCH FIRST FROM test_cursor INTO @a
PRINT @a --取当前位置的第n行数据(取绝对位置)
FETCH ABSOLUTE FROM test_cursor INTO @a
PRINT @a --取相对位置
FETCH RELATIVE FROM test_cursor INTO @a
PRINT @a --取当前位置的下一行数据
FETCH NEXT FROM test_cursor INTO @a
PRINT @a
--取最后一条数据
FETCH LAST FROM test_cursor INTO @a
PRINT @a
--取游标的当前位置的上一行数据
FETCH PRIOR FROM test_cursor INTO @a
PRINT @a --游标使用完之后需要关闭游标
CLOSE test_cursor --如果不再需要游标,可以进行删除
DEALLOCATE test_cursor

游标经常会和全局变量 @@Fetch_status 与while循环来共同使用,以便达到遍历游标所在数据集的目的

例如:

DECLARE Test_Cursor CURSOR SCROLL FOR
SELECT c.Id,c.Nickname FROM Customer AS c OPEN Test_Cursor
DECLARE @i INT
DECLARE @name NVARCHAR() WHILE @@FETCH_status =
BEGIN
PRINT @i
PRINT @name
FETCH NEXT FROM Test_Cursor INTO @i,@name
END
CLOSE Test_Cursor
DEALLOCATE Test_Cursor

使用游标注意点:

1 游标能不用就尽量不要用游标
2 用完之后一定要关闭和释放
3 尽量不要在大量数据上定义游标
4尽量不要使用游标上更新数据
5 尽量不要使用insensitive,static,keyset这些参数定义游标
6 如果可以,尽量使用fast_forward关键字定义游标
7如果只对数据进行读取,当读取只用到Fetch next选项,则最好使用 forward_only参数

Sqlserver 关于游标的更多相关文章

  1. SqlServer之游标深入

    原创文章,转载必需注明出处:http://www.ncloud.hk/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/introduce-for-sqlserver-curs ...

  2. SqlServer 利用游标批量更新数据

    SqlServer 利用游标批量更新数据 Intro 游标在有时候会很有用,在更新一部分不多的数据时,可以很方便的更新数据,不需要再写一个小工具来做了,直接写 SQL 就可以了 Sample 下面来看 ...

  3. 【SqlServer】SqlServer的游标使用

    什么是游标 结果集,结果集就是select查询之后返回的所有行数据的集合. 游标则是处理结果集的一种机制吧,它可以定位到结果集中的某一行,多数据进行读写,也可以移动游标定位到你所需要的行中进行操作数据 ...

  4. SQLServer中游标是如何处理数据的?

    游标(Cursor)是处理数据的一种方法,为了查看或者处理结果集中的数据,游标提供了在结果集中一次以行或者多行前进或向后浏览数据的能力.我们可以把游标当作一个指针,它可以指定结果中的任何位置,然后允许 ...

  5. sqlserver 使用游标过程中出现的错误

    下面的见解是在使用游标的过程中做的日记.我也是第一次使用,如果有什么不对的地方请批评指正,大家一起努力. 1. 消息 16951,级别 16,状态 1,过程 usp_proc,第 16 行      ...

  6. SQLServer中游标实例介绍(转)

    引言 我们先不讲游标的什么概念,步骤及语法,先来看一个例子: 表一 OriginSalary                      表二 AddSalary 现在有2张表,一张是OriginSal ...

  7. SQLserver 存储过程游标使用

    ALTER PROCEDURE [dbo].[p_DeleteStretchData] ) , ) AS BEGIN ) ) declare @stretch_cursor cursor -- 声明游 ...

  8. 使用sqlserver的游标功能来导数据的常见写法

    一定要自己试过才知道么? 你也没试过吃屎,你怎么知道屎不能吃,难道你试过啊...(没有愤怒的意思) ),),) declare cursor_data CURSOR FOR SELECT [UserN ...

  9. sqlserver 存储过程 游标实例

    if exists(select * from sysobjects where id = object_id(N'dbo.test_cursor') and type = 'P') drop PRO ...

随机推荐

  1. sqlserver2012

    sqlserver2012作死的节奏啊,微软最近怎么了?搞个sqlserver2012死活安装不上,无论如何都是.NET Framework 4报错,机器本身的版本比安装包的高就报错?微软的程序员思维 ...

  2. ssm框架查询数据并实现分页功能示例

    /** * DataGrid对象 * */ @SuppressWarnings("rawtypes") public class DataGrid { private int to ...

  3. Cocos2d-x——Cocos2d-x 屏幕适配新解【转载】

    Cocos2d-x 屏幕适配新解 本文出自[无间落叶](转载请保留出处):http://blog.leafsoar.com/archives/2013/05-10-19.html 为了适应移动终端的各 ...

  4. 参数对象Struts2中Action的属性接收参数

    题记:写这篇博客要主是加深自己对参数对象的认识和总结实现算法时的一些验经和训教,如果有错误请指出,万分感谢. Action中三种传递并接受参数: 1.  在Action添加成员属性接受参数 例如请求的 ...

  5. hdu 5587 Array 数学题

    Array Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5587 De ...

  6. c# 自己制作一个简单的项目倒计时器

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  7. 飘逸的python - 编码杂症之在字符串前面加u

      有时候我们从其它地方接受的字符串经过艰难跋涉,它变了个样.比如收到的是'\u6253\u602a\u8005'而不是u'\u6253\u602a\u8005'. 明明肉眼看起来只需要加个u,但是怎 ...

  8. android 访问SMS短信收件箱

    访问 SMS收件箱是另一个常见的需求.首先,需要将读取 SMS 的权限   <uses-permission android:name="android.permission.READ ...

  9. Asp.Net MVC 3【URLs, Routing,and Areas】续

    http://www.cnblogs.com/HuiTai/archive/2012/07/24/2597875.html 接着前面继续学习分享我们的路由. 现在我们把Global.asax文件里的R ...

  10. flash 入门课知识小结

    一. 几种类型帧的小结:(关键帧.空白关键帧.普通帧)1. 特点  帧——是进行flash动画制作的最基本的单位,每一个精彩的flash动画都是由很多个精心雕琢的帧构成的,在时间轴上的每一帧都可以包含 ...