为什么使用游标:
普通查询:把集合或多集作为一个整体来处理,不依赖任何顺序;
游标对象查询:它用来处理查询返回的结果集中的各行,以指定的顺序一次只处理一行;
使用游标的步骤:
在某个查询的基础上声明游标;
打开游标;
从第一个游标记录中把列值提取到指定的变量;
当还没有超出游标的最后一行时(@@FETCH_STATUS函数的返回值是0),循环遍历游标记录:在每一次遍历中,从当前游标记录中把列值提取到指定的变量,再为当前行执行相应的处理。
关闭游标;
释放游标;
例子 : 使用游标来计算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 FROM C INTO @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;