为什么使用游标:

  • 普通查询:把集合或多集作为一个整体来处理,不依赖任何顺序;

  • 游标对象查询:它用来处理查询返回的结果集中的各行,以指定的顺序一次只处理一行;

使用游标的步骤:

  1. 在某个查询的基础上声明游标;

  2. 打开游标;

  3. 从第一个游标记录中把列值提取到指定的变量;

  4. 当还没有超出游标的最后一行时(@@FETCH_STATUS函数的返回值是0),循环遍历游标记录:在每一次遍历中,从当前游标记录中把列值提取到指定的变量,再为当前行执行相应的处理。

  5. 关闭游标;

  6. 释放游标;

例子 : 使用游标来计算Sales.CustOrders视图中每个客户每个月的连续总订货量:

--(代码逻辑:

-- 声明游标 --CustOrder视图中按客户ID和订单月份的顺序返回基本数据行;

--通过循环来遍历每个记录,代码不断跟踪客户的当前连续订货量,并将值保存在变量@runqty中,每次找到一个客户,重置该变量。再把客户ID,订单月份,当前月订货量,当前月的连续订货量作为一行插入到表变量@result中。

--@qty : 当月的订货量

--@runqty: 当前月的连续订货量

--当完成游标的所有记录后,再查询表变量以显示生成的连续聚合值。

--)

Set nocount on  --不返回T-SQL 影响的行数,计数;

UseTSQLFundamentals2008

Declare @result table

(

Custid int,

Ordermonth datetime,

Qty int,

Runqty int,

Primary key(custid,ordermonth)

);

Declare

@custid as int,

@prvcustid as int,

@ordermonth datetime,

@qty as int,

@runqty as int;

 

--Step 1在某个查询的基础上声明游标

Declare C Cursor fast_forward /*read only, forward only*/ for

  Select custid, ordermonth, qty

From sales.custorders

Order by custid, ordermonth;

 

--Step 2: 打开游标

Open C

 

--Step 3: 从第一个游标记录中把列值提取到指定的变量;

FETCH NEXT FROMINTO @custid, @ordermonth, @qty;

Select @prvcustid=@custid, @runqty=0;

 

--Step 4: 当还没有超出游标的最后一行时(@@FETCH_STATUS函数的返回值是0),循环遍历游标记录:在每一次遍历中,从当前游标记录中把列值提取到指定的变量,再为当前行执行相应的处理。

 

WHILE @@FETCH_STATUS = 0

BEGIN

IF @custid <> @prvcustid

     Select@prvcustid = @custid,@runqty=0;

Set @runqty =@runqty +@qty;

Insert into @result values(@custid,@ordermonth,@qty,@runqty);

Fetch next from C INTO @custid,@ordermonth, @qty

END

 

--Step 5: 关闭游标;

CLOSE C;

 

--Step 4: 释放游标;

DEALLOCATE C;

 

--当完成游标的所有记录后,再查询表变量以显示生成的连续聚合值。

Select

   Custid,

   Convert(varchar(7),ordermonth,121) as ordermonth,

   Qty,

   Runqty

   From @result

Order by custid, ordermonth;