SQL Server中用While循环替代游标(Cursor)的解决方案

By行处理数据,推荐2种方式:

1、游标

2、While循环

我们来了解下这两种方案处理1w行数据分别需要多长时间。

一、游标。

首先我们填充一个表,用优雅的递归方式填充。

create table Orders(OrderID int,CostValue decimal(18,2) )

;with cte_temp
as
(
    select 1 as OrderID
    union all
    select OrderID+1 from cte_temp where OrderID<10000
)

insert into Orders(OrderID)
select OrderID from cte_temp option (maxrecursion 32767);

 现在我们的订单表Orders有了一万条订单,但是CostValue还是NULL值。

我们用游标的方式给每一条订单添加一个CostValue,耗时44s。

--游标
DECLARE @OrderID int

DECLARE cursor_CostValue CURSOR FOR  SELECT OrderID FROM Orders
OPEN cursor_CostValue
FETCH NEXT FROM cursor_CostValue INTO @OrderID
WHILE @@FETCH_STATUS = 0
BEGIN
    UPDATE Orders SET CostValue = OrderID+100 WHERE OrderID = @OrderID
    FETCH NEXT FROM cursor_CostValue INTO @OrderID
END
CLOSE cursor_CostValue  
DEALLOCATE cursor_CostValue

 

 二、While循环

将数据放在临时表中,然后操作临时表,最后更新回总表。耗时16s。

DECLARE @RowID int
      
--    获取待处理的数据记录到临时表
--    字段说明:RowID:记录行号 / DealFlg:行处理标识
SELECT  RowID = IDENTITY(INT , 1, 1),DealFlg=0,OrderID,CostValue = 0
INTO #Tmp
FROM Orders
SELECT @RowID = MIN(RowID) FROM #Tmp WHERE DealFlg = 0
--    若最小行号不为空(有需要处理的数据)
WHILE @RowID IS NOT NULL
BEGIN
    UPDATE #Tmp SET DealFlg = 1,CostValue=OrderID+100 WHERE RowID = @RowID

    SELECT @RowID = MIN(RowID) FROM #Tmp WHERE DealFlg = 0
END
update O set O.CostValue=T.CostValue
from Orders O
    inner join #Tmp T on O.OrderID=T.OrderID

 

还有一种错误的While循环,即不把数据放在临时表中,直接操作本表,会大大增加耗时。

因为多次调用本表,如果在生产环境,将是一个灾难。

DECLARE @OrderID INT   
--表中OrderID最小的值
SELECT @OrderID = MIN(OrderID) FROM Orders where CostValue is null
WHILE @OrderID IS NOT NULL
BEGIN
    UPDATE Orders SET CostValue = OrderID+100 WHERE OrderID = @OrderID
    SELECT @OrderID = MIN(OrderID) FROM Orders where CostValue is null
END

 

参考链接:http://www.cnblogs.com/swq6413/archive/2012/09/01/2667190.html

转载于:https://www.cnblogs.com/SunnyZhu/p/5719184.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值