对于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. Parallax Mapping Shader 凸凹感【转】

    原文 http://www.azure.com.cn/default.asp?cat=11&page=2 Parallax Mapping 就是通过高度图中的高度,对纹理坐标进行偏移,来视觉上 ...

  2. ListView 文件重命名

          unit Unit1; interface uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Control ...

  3. [Codeforces] 347B - Fixed Points

    题意:给定一个序列,现有一种操作:两个数的位置互换.问最多操作一次.序列 [元素位置i]  与 [元素Ai] 相等的最多个数? 依据题意,最多个数为 : [操作之前[元素位置i]  与 [元素Ai] ...

  4. Blueprint编译过程

    Blueprint 编译概述 一.术语 Blueprint,像C++语言一下的,在游戏中使用前须要编译.当你在BP编辑器中,点击编译button时候.BP资源開始把属性和图例过程转换为一个类对象处理. ...

  5. mysql_upgrade命令

    mysql 创建存储过程失败.查看错误日志,发现如下信息:*********************************************************************** ...

  6. MySQL Router 测试使用 转

    MySQL Router 测试使用 . 特性 MySQL Router 并没有包括一些特别新的特性, 总体上看中规中矩, 不过 first-available 和插件两个特性挺有意思, 后续会进行讲解 ...

  7. Tomcat以指定JDK运行

    如果一台机器上有多个Tomcat,可能存在不同的Tomcat需要不同版本JDK才能运行的情况,这时候就需要指定JDK来同时运行多个Tomcat了. 在windows环境下以批处理文件方式启动tomca ...

  8. mysql 支持emoji

    1.修改my.cnf [client] default-character-set = utf8mb4 [mysqld] collation-server = utf8mb4_unicode_ci c ...

  9. Line Search and Quasi-Newton Methods

    Gradient Descent 机器学习中很多模型的参数估计都要用到优化算法,梯度下降是其中最简单也用得最多的优化算法之一.梯度下降(Gradient Descent)[3]也被称之为最快梯度(St ...

  10. 带约束优化问题 拉格朗日 对偶问题 KKT条件

    转自:七月算法社区http://ask.julyedu.com/question/276 咨询:带约束优化问题 拉格朗日 对偶问题 KKT条件 关注 | 22 ... 咨询下各位,在机器学习相关内容中 ...