参考资料
http://technet.microsoft.com/zh-cn/library/ms181441(v=sql.105).aspx
一、游标概念
我们知道,关系数据库所有的关系运算其实是集合与集合的运算,它的输入是集合输出同样是集合,有时需要对结果集逐行进行处理,这时就需要用到游标。我们对游标的使用一本遵循“五步法”:声明游标—>打开游标—>读取数据—>关闭游标—>删除游标。以下就从这五步对游标的使用进行说明,并给出具体实例。

二、“五步法”讲解
1、声明游标(DECLARE CURSOR)
(1) DECLARE CURSOR 既接受基于 ISO 标准的语法,也接受使用一组 Transact-SQL 扩展的语法。
复制代码
ISO 语法
DECLARE cursor_name [ INSENSITIVE ] [ SCROLL ] CURSOR
FOR select_statement
[ FOR { READ ONLY | UPDATE [ OF column_name [ ,…n ] ] } ]
[;]

Transact-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 ] ] ]
[;]
复制代码
下面只对“T-SQL扩展语法”进行介绍,主要游标介绍作用域、方向及类型

(2)游标的作用域
LOCAL

  说明所声明的游标为局部的,其作用域为创建它的批处理、存储过程或触发器,即在批处理、调用它的存储过程或触发器执行完成后,该游标被系统隐式释放。但,若游标作为存储过程OUTPUT 的输出参数,在存储过程终止后给游标变量分配参数可以继续引用游标,如果 OUTPUT 参数将游标传递回来,则游标在最后引用它的变量释放或离开作用域时释放。

GLOBAL

  指定该游标的作用域对来说连接是全局的。在由连接执行的任何存储过程或批处理中,都可以引用该游标名称。该游标仅在断开连接时隐式释放。注意:如果 GLOBAL 和 LOCAL 参数都未指定,则默认值由 default to local cursor 数据库选项的设置控制。在 SQL Server 7.0 版中,该选项默认为 FALSE,以便与 SQL Server 的早期版本匹配,在早期版本中,所有游标都是全局的。

复制代码
declare testcur cursor --声明时未指定"local"或"global"关键字,系统默认游标是"global(全局)"的.
for
select 学号,姓名 from XSB
GO
open testcur
fetch next from testcur
GO

declare testcur cursor local --声明时指定"local"关键字
for
select 学号,姓名 from XSB
open testcur
fetch next from testcur
GO --在这个批处理结束后,游标自动释放,即失效

declare testcur1 cursor local --声明时指定"local"关键字
for
select 学号,姓名 from XSB
GO --在这个批处理后,游标就失效了,后面对游标操作时,提示"名为 ‘testcur1’ 的游标不存在"错误.
open testcur1
fetch next from testcur1
GO
复制代码
(3)游标方向
FORWARD_ONLY

  指定游标只能从第一行滚动到最后一行。FETCH NEXT 是唯一支持的提取选项。如果在指定 FORWARD_ONLY 时不指定 STATIC、KEYSET 和 DYNAMIC 关键字,则游标作为 DYNAMIC 游标进行操作。如果 FORWARD_ONLY 和 SCROLL 均未指定,则除非指定 STATIC、KEYSET 或 DYNAMIC 关键字,否则默认为 FORWARD_ONLY。STATIC、KEYSET 和 DYNAMIC 游标默认为 SCROLL。与 ODBC 和 ADO 这类数据库 API 不同,STATIC、KEYSET 和 DYNAMIC Transact-SQL 游标支持 FORWARD_ONLY。

SCROLL

 指定所有的提取选项(FIRST、LAST、PRIOR、NEXT、RELATIVE、ABSOLUTE)均可用。如果未在 ISO DECLARE CURSOR 中指定 SCROLL,则 NEXT 是唯一支持的提取选项。如果也指定了 FAST_FORWARD,则不能指定 SCROLL。

复制代码
declare directionCur cursor --不指定移动方向,则默认为“forward_only”
for
select 学号,姓名 from XSB
Go
open directionCur
fetch next from directionCur
Go
fetch prior from directionCur --错误“提取类型 prior 不能与只进游标一起使用。”
Go
close directionCur2
deallocate directionCur2
Go

declare directionCur1 cursor forward_only --指定“forward_only”方向
for
select 学号,姓名 from XSB
Go
open directionCur1
fetch next from directionCur1
Go
fetch prior from directionCur1 --错误“提取类型 prior 不能与只进游标一起使用。”
Go
close directionCur2
deallocate directionCur2
Go

declare directionCur2 cursor scroll --指定“scroll”方向
for
select 学号,姓名 from XSB
Go
open directionCur2
fetch next from directionCur2
Go
fetch prior from directionCur2
Go
close directionCur2
deallocate directionCur2
Go

–结论:若游标没有指定任何访问或类型参数,则默认为全局、只进、动态游标。(这是在SQLServer2008 R2上的测试结果,具体取决于软件设置)

–"scroll"和"fast_forward"不能一起使用
declare forwardTest cursor scroll fast_forward --报错“游标选项 SCROLL 和 FAST_FORWARD 冲突。”
for
select 学号,姓名 from XSB
Go

–在 SQL Server 2000 中,FAST_FORWARD 和 FORWARD_ONLY 游标选项是互相排斥的。如果指定了二者,则会引发错误。
–在 SQL Server 2005 及更高版本中,这两个关键字可以用在同一个 DECLARE CURSOR 语句中。
declare forwardTest1 cursor forward_only fast_forward
for
select * from XSB
Go
复制代码
(4)游标类型
STATIC

 定义一个游标,以创建将由该游标使用的数据的临时复本。对游标的所有请求都从 tempdb 中的这一临时表中得到应答;因此,在对该游标进行提取操作时返回的数据中不反映对基表所做的修改,并且该游标不允许修改。及该游标是只读的。

KEYSET

 指定当游标打开时,游标中行的成员身份和顺序已经固定。对行进行唯一标识的键集内置在 tempdb 内一个称为 keyset 的表中。

DYNAMIC

  定义一个游标,以反映在滚动游标时对结果集内的各行所做的所有数据更改。行的数据值、顺序和成员身份在每次提取时都会更改。

FAST_FORWARD

  指定启用了性能优化的 FORWARD_ONLY、READ_ONLY 游标。如果指定了 SCROLL 或 FOR_UPDATE,则不能也指定 FAST_FORWARD。

2、打开游标(OPEN)
语法
OPEN { { [ GLOBAL ] cursor_name } | cursor_variable_name }
示例
复制代码
–打开游标并读取所有行
declare XSBcur cursor --声明
for
Select * from XSB
Go
open XSBcur --打开
fetch next from XSBcur --获取数据
while @@FETCH_STATUS = 0
begin
fetch next from XSBcur
end
close XSBcur --关闭
deallocate XSBcur --删除
复制代码
全局变量 @@CURSOR_ROWS

该变量保存着最后打开的游标中的数据行数,当其值为0时,表示没有游标打开;其值为-1时,表示游标为动态的;当其值为-m(m为正整数)时,游标采用异步方式填充,m为当前键集中已填充的

行数;当其值为m(m为正整数)时,游标已被完全填充,m是游标中的数据行数。

3、读取数据
语法
复制代码
FETCH
[ [ NEXT | PRIOR | FIRST | LAST
| ABSOLUTE { n | @nvar }
| RELATIVE { n | @nvar }
]
FROM
]
{ { [ GLOBAL ] cursor_name } | @cursor_variable_name }
[ INTO @variable_name [ ,…n ] ] --into说明将读取的游标数据存放到指定的变量中
复制代码
示例
复制代码

declare stuCur cursor scroll
for
select 学号,姓名 from XSB
GO
open stuCur
Go
–读取数据开始
fetch next from stuCur --读取当前行的下一行,并使其置为当前行(刚开始时游标置于表头的前一行,即若表是从0开始的,游标最初置于-1处,所以第一次读取的是头一行)
fetch prior from stuCur --读取当前行的前一行,并使其置为当前行
fetch first from stuCur --读取游标的第一行,并使其置为当前行(不能用于只进游标)
fetch last from stuCur --读取游标的最后一行,并使其置为当前行(不能用于只进游标)
fetch absolute 2 from stuCur --读取从游标头开始向后的第2行,并将读取的行作为新的行
fetch relative 3 from stuCur --读取从当前行开始向后的第3行,并将读取的行作为新的行
fetch relative-2 from stuCur --读取当前行的上两行,并将读取的行作为新的行
–读取数据结束
GO
close stuCur
Go
deallocate stuCur
Go

复制代码
全局变量 @@FETCH_STATUS

FETCH语句的执行状态保存在全局变量@@FETCH_STATUS中,其值为0表示上一个FETCH执行成功;为-1表示所要读取的行不在结果集中;为-2表示被提取的行已不存在(已被删除)。

4、关闭游标(CLOSE)
语法
CLOSE { { [ GLOBAL ] cursor_name } | cursor_variable_name }
示例
close stuCur --若该游标事先声明并已打开
Go

5、删除游标(DEALLOCATE)
对游标进行操作的语句使用游标名称或游标变量引用游标。DEALLOCATE 删除游标与游标名称或游标变量之间的关联。如果一个名称或变量是最后引用游标的名称或变量,则将释放游标,游标使用的任何资源也随之释放。用于保护提取隔离的滚动锁在 DEALLOCATE 上释放。用于保护更新(包括通过游标进行的定位更新)的事务锁一直到事务结束才释放。

语法
DEALLOCATE { { [ GLOBAL ] cursor_name } | @cursor_variable_name }
示例
游标变量使用下列两种方法之一与游标关联:

复制代码
–声明一个游标
declare abc cursor scroll
for
select * from XSB

–(1)通过名称,使用set语句将游标设置为游标变量
declare @mycur cursor
set @mycur = abc

–(2)也可以不定义游标名称而创建游标并将其与变量关联
declare @mycursor cursor
set @mycursor = cursor local scroll for
Select * from XSB
复制代码
DEALLOCATE @cursor_variable_name 语句只删除对游标名称变量的引用。直到批处理、存储过程或触发器结束时变量离开作用域,才释放变量。在 DEALLOCATE @cursor_variable_name 语句之后,可以使用 SET 语句将变量与另一个游标关联。游标可以理解为指针。

复制代码
declare @mycur cursor
set @mycur = cursor local scroll for
select * from XSB

deallocate @mycur

set @mycur = cursor local scroll for
select * from XSB
GO
–不必显式释放游标变量。变量在离开作用域时被隐式释放。
复制代码
以下脚本显示游标如何持续到最后的名称或持续到引用它们的变量已释放。

复制代码
USE AdventureWorks2008R2;
GO
– Create and open a global named cursor that
– is visible outside the batch.
DECLARE abc CURSOR GLOBAL SCROLL FOR
SELECT * FROM Sales.SalesPerson;
OPEN abc;
GO
– Reference the named cursor with a cursor variable.
DECLARE @MyCrsrRef1 CURSOR;
SET @MyCrsrRef1 = abc;
– Now deallocate the cursor reference.
DEALLOCATE @MyCrsrRef1;
– Cursor abc still exists.
FETCH NEXT FROM abc;
GO
– Reference the named cursor again.
DECLARE @MyCrsrRef2 CURSOR;
SET @MyCrsrRef2 = abc;
– Now deallocate cursor name abc.
DEALLOCATE abc;
– Cursor still exists, referenced by @MyCrsrRef2.
FETCH NEXT FROM @MyCrsrRef2;
– Cursor finally is deallocated when last referencing
– variable goes out of scope at the end of the batch.
GO
– Create an unnamed cursor.
DECLARE @MyCursor CURSOR;
SET @MyCursor = CURSOR LOCAL SCROLL FOR
SELECT * FROM Sales.SalesTerritory;
– The following statement deallocates the cursor
– because no other variables reference it.
DEALLOCATE @MyCursor;
GO
复制代码
三、用到的数据
1、创建表的脚本
复制代码
CREATE TABLE [dbo].[XSB](
[学号] char NOT NULL,
[姓名] char NOT NULL,
[性别] [bit] NULL,
[出生时间] [date] NULL,
[专业] char NULL,
[总学分] [int] NULL,
[备注] varchar NULL,
PRIMARY KEY CLUSTERED
(
[学号] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
复制代码
2、插入数据
复制代码
insert into XSB values
(‘081101’,‘王林’,‘true’,‘1990-2-10’,‘计算机’,50,null),
(‘081102’,‘陈平’,‘true’,‘1991-2-1’,‘计算机’,50,null),
(‘081103’,‘王燕’,‘false’,‘1989-10-6’,‘计算机’,50,null),
(‘081104’,‘韦严平’,‘true’,‘1990-8-26’,‘计算机’,50,null),
(‘081106’,‘李芳芳’,‘true’,‘1990-11-20’,‘计算机’,50,null),
(‘081107’,‘李明’,‘true’,‘1990-5-1’,‘计算机’,54,‘已提前修完数据结构,并获学分’),
(‘081108’,‘林一凡’,‘true’,‘1989-8-5’,‘计算机’,52,‘已提前修完一门课’),
(‘081109’,‘张强民’,‘true’,‘1989-8-11’,‘计算机’,50,null),
(‘081110’,‘张蔚’,‘false’,‘1991-7-22’,‘计算机’,50,‘三好生’),
(‘081111’,‘赵琳’,‘false’,‘1989-10-6’,‘计算机’,50,null),
(‘081113’,‘严红’,‘false’,‘1989-8-11’,‘计算机’,48,‘一门不及格,待补考’),
(‘081201’,‘王敏’,‘true’,‘1989-6-10’,‘通信工程’,42,null),
(‘081202’,‘王林’,‘true’,‘1989-6-10’,‘通信工程’,40,‘一门不及格,待补考’)
GO
复制代码

SQLServer游标详解相关推荐

  1. sql server 中游标详解

    目录 游标的定义 种类:(我也不太理解,有理解的@我) 游标的类型: 游标的实现 游标的实现功能 游标的使用的步骤: 游标的使用: 1.声明游标 游标的格式:(看了很多版本的格式说明, 这是最好理解的 ...

  2. oracle cusor游标,ORACLE CURSOR 游标详解

    DECLARE sqlStr       VARCHAR2(2000); --拼写sql flag         int; --判断是否存在 col_name     VARCHAR2(100); ...

  3. C#连接sqlServer数据库详解

    C# 是如何跟SQL Server进行连接的? 在C#/.NET程序设计中,离不开ADO.NET.ADO.NET是.NET连接数据库的重要组件.使用其可以很方便地访问数据库,ADO.NET还可以访问O ...

  4. Oracle cursor 游标详解

    文章目录 1 概述 1.1 思维导图 2 语法 2.1 基本写法(4步) 2.2 游标4大属性 3 分类 3.1 静态游标 3.1.1 隐式游标 dml 3.1.2 显式游标 cursor 3.2 动 ...

  5. ORACLE游标详解

    文章目录 一.概述 二.显示游标 1.声明游标 2.打开游标 3.读取游标 4.关闭游标 三.隐式游标 四.游标的属性 1.%FOUND(是否找到游标) 2.%NOTFOUND(是否没找到游标) 3. ...

  6. 服务器上怎样开启sql远程,如何开启SqlServer 远程访问详解(图文并茂)

    这篇文章主要介绍了如何开启SqlServ­er 远程访问,本文图文并茂给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下 当Mi­crosoft Sqlserv­er XXXX安装好后 ...

  7. sqlserver数据库详解

    第一节:主要内容: 数据库的基础知识:基本概念.数据库组成,数据类型,数据库操作,管理.数据的支持,winform,网站,百度 数据库:DataBase 按照一定数据结构来组织.存储和管理数据的仓库. ...

  8. sqlserver触发器详解:sqlserver触发器after/for和instead of的区别详解(实例讲解),触发器定义创建操作打通,触发器的优缺点,触发器使用建议

    文章目录 1.触发器介绍 2.特点 3.DML触发器分类 4.inserted表与deleted表 4.1 表介绍 4.2 创建时机 5.定义触发器 5.1 定义触发器 5.2 分类 5.2.1 AF ...

  9. sql server 存储过程的详解

    SqlServer存储过程详解 1.创建存储过程的基本语法模板: if (exists (select * from sys.objects where name = 'pro_name'))drop ...

  10. MySQL数据库,从入门到精通:第十四篇——MySQL视图详解

    MySQL数据库,从入门到精通:第十四篇--MySQL视图详解 第 14 篇_视图 1. 常见的数据库对象 2. 视图概述 2. 1 为什么使用视图? 2. 2 视图的理解 3. 创建视图 3. 1 ...

最新文章

  1. .NET代码编写规范 整理
  2. linux sock_raw原始套接字编程
  3. 产品设计的Kawaiization
  4. LeetCode 第 23 场双周赛(970/2044,前47.5%)
  5. LEADTOOLS概览
  6. 微信支付curl: (60) SSL certificate problem: unable to get local issuer certificate 解决方法
  7. js控制隐藏或显示table的某一行
  8. keepalived详解(一)——keepalived理论基础
  9. 【排错】exchange2013不能显示所有OU
  10. 迈高图手机版_迈高图(地图数据下载器)
  11. java cmd 进程_关闭CMD进程-JAVA
  12. 【JS】中文繁简转换
  13. 网站目标定位的关键词和选择质量高的关键词
  14. qq(q音乐)扫码授权登陆分析及python实现
  15. [微信]微信小程序开发--用户昵称中带有emoji表情的处理方法
  16. 学习Hibernate框架笔记-第2天
  17. Python爬虫笔记
  18. unity Font字体替换
  19. asp.net 将中文翻译成拼音(VS2008)
  20. 服务器cpu型号大变更,英特尔新世代Xeon Scalable服务器处理器登场,架构大翻新拥有超多28核心,更改采分级制推4大产品线...

热门文章

  1. Firefox扩展插件开发extension代码调试方法
  2. 2019年密码与安全新技术讲座-课程总结报告
  3. 幸运福彩3d 是什么
  4. 会声会影2022Win64中文版特别版
  5. matlab单回路控制系统设计,实验二单回路控制系统的建模与仿真 .doc
  6. centos6 yum安装tomcat8
  7. SIFT算法 特征匹配
  8. ESP8266开发之旅 应用篇② OLED显示天气屏
  9. C语言:大小字母转换(ASCII码)
  10. 宝塔面板6.9.0一键破解脚本