zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    改进的二分查找
    关于Java并发编程的总结和思考
    java异常捕获案例,此题的出处是《Java编程思想》一书
    一道关于int和Integer的面试题
    看《韩顺平Java》视频的笔记
    spring task 定时任务执行两次
    记录
    Java基础面试题
    TeamViewer修改绑定设备
    jqGrid常用操作
  • 原文地址:https://www.cnblogs.com/SunnyZhu/p/5719184.html
Copyright © 2011-2022 走看看