不带ORDER BY 子句的查询返回的是一个集合(或多集),而带有ORDER BY 子句的查询返回的是一种ANSI 称为游标(cursor)的对象,由于这种结果的行之间具备固定的顺序,因此不是关系的结果。函数
在默认状况下应该使用基于集合的查询,只在有使人信服的理由时才考虑使用游标。对象
由于基础
1.若是使用游标,就严重违背了关系模型,关系模型要求按照集合来考虑问题。变量
2.游标逐行对记录进行操做会带来必定的开销。和基于集合的操做相比,游标分别对每一记录进行操做,这确定会带来必定的额外开销。给定一个基于集合的查询,以及一段在幕后用游标完成相似物理处理的代码,游标代码一般比基于集合的代码要慢许多倍。循环
3.使用游标,须要为解决方案的物理操做编写不少代码,换句话说,得写不少代码来描述如何处理数据(声明游标、打开游标、循环遍历游标记录、关闭游标、释放游标)。而使用基于集合的解决方案,则主要关注于问题的逻辑方面,也就是说,只要描述要获取什么,而没必要描述如何获取它们。所以,与基于集合的解决方案相比,基于游标的解决方案一般代码更长,可读性更低,也更加难以维护。遍历
使用游标一般涉及如下步骤:数据
1. 在某个查询的基础上声明游标。查询
2. 打开游标。db
3. 从第 1 个游标记录中把列值提取到指定的变量。集合
4. 当尚未超出游标的最后一行时(@@FETCH_STATUS 函数的返回值是0),循环遍历游标记录;在每一次遍历中,从当前游标记录中把列值提取到指定的变量,再为当前行执行相应的处理。
5. 关闭游标。
6. 释放游标。
DECLARE @ID intDECLARE @Name nvarchar(max)DECLARE C CURSOR FOR SELECT categoryId,categoryname FROM dbo.Categories -- 定义游标OPEN C -- 打开游标FETCH NEXT FROM C INTO @ID,@Name -- 移向第一个游标--SELECT @ID+@NameWHILE @@FETCH_STATUS=0BEGIN SELECT str(@ID)+@Name FETCH NEXT FROM C INTO @ID,@Name --移向下一条数据ENDCLOSE C; -- 关闭游标DEALLOCATE C -- 释放游标