remington_young 发表于 2018-10-23 08:11:38

15. SQL -- 游标(实例)

  为什么使用游标:

[*]  普通查询:把集合或多集作为一个整体来处理,不依赖任何顺序;
[*]  游标对象查询:它用来处理查询返回的结果集中的各行,以指定的顺序一次只处理一行;
  使用游标的步骤:

[*]  在某个查询的基础上声明游标;
[*]  打开游标;
[*]  从第一个游标记录中把列值提取到指定的变量;
[*]  当还没有超出游标的最后一行时(@@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 CINTO @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;

页: [1]
查看完整版本: 15. SQL -- 游标(实例)