【问题标题】:Inserting Rows and Updating a Table without using SQL Cursor在不使用 SQL 游标的情况下插入行和更新表
【发布时间】:2011-06-16 02:00:12
【问题描述】:

我正在尝试创建一个 MS SQL 2005 存储过程,以便为订单中的特定组件从仓库分配库存。有多批库存可用,并且必须按特定顺序使用。我可以遍历可用库存并进行分配,直到订单完成,但我试图更多地考虑基于集合而不是顺序,并避免使用 CURSOR。

这是我的查询,用于获取可用于特定订单组件的仓库库存;

SELECT 
        STOCK.ComponentId,
        STOCK.StockId,
        STOCK.ExpiryDate, 
        STOCK.BatchNo, 
        STOCK.StockQty, 
        ORDER_ITEMS.OrderQty        
    FROM 
        STOCK 
        JOIN ORDER_ITEMS ON ORDER_ITEMS.ComponentId = STOCK.ComponentId 
    WHERE 
        STOCK.WarehouseId = @WarehouseId 
        AND STOCK.StockQty > 0
        AND ORDER_ITEMS.OrderItemId = @OrderItemId

我一直将它放入临时表或使用查询创建 CTE 并应用 ORDER BY 子句以在需要用完时对库存进行排序。这给了我一个类似的结果集:

ComponentId | StockId | ExpiryDate | BatchNo  | StockQty | OrderQty
-------------------------------------------------------------------
359         | 3107    | 2013-10-01 | 132435-1 | 20       | 50
359         | 3215    | 2013-10-01 | 154558-1 | 100      | 50
359         | 3216    | 2014-01-01 | 154689-1 | 100      | 50

我需要做的是将记录插入到STOCK_ALLOCATED 表中,使用尽可能多的库存批次来满足订单数量。在上面的示例中,我将使用第一行中的所有 20 个,然后需要第二行中的 30 个。

这需要在STOCK_ALLOCATED 表中插入两条记录,其中OrderItemIdStockId 和两个已用批次的数量(20 和30),同时减少STOCK 表中的库存数量适当的。

假设必要的事务已经到位以始终如一地维护库存表,有没有一种方法可以在不使用 CURSOR 循环并跟踪我已经分配多少库存以及我还需要多少库存的情况下进行插入和更新?

【问题讨论】:

    标签: sql sql-server sql-server-2005 stored-procedures cursor


    【解决方案1】:

    这是一个适合您的测试样本:

    SELECT  
        StockID,
        Quantity
    FROM (
        SELECT  
            StockID,
            CASE 
                WHEN OrderQty - PreviousQty <= 0 THEN 0
            ELSE 
                    CASE 
                        WHEN OrderQty - PreviousQty <= Stock 
                        THEN OrderQty - PreviousQty 
                    ELSE
                        Stock 
                    END
            END Quantity
        FROM (
            SELECT  
                a.StockID,
                a.Stock,
                a.OrderQty,
                a.OrderByField,
                ISNULL(SUM(b.Stock), 0) PreviousQty
            FROM    
                @Table a
                LEFT JOIN @Table b ON a.OrderByField > b.OrderByField
            GROUP BY a.StockID,
                a.Stock,
                a.OrderQty,
                a.OrderByField
            ) Orders
        ) Orders
    WHERE   Quantity > 0
    

    基本上,您需要将自己获得的结果加入其中,这样您就可以将先前保留数量的数量相加,然后从 StockQty 中减去该数量,以确定您还需要完成什么。

    不过,为了做到这一点,您将需要一个唯一的 OrderByField,以便您可以准确地过滤掉以前的 StockQty 值。如果您没有可以使用的存储值,则可以使用ROW_NUMBER() OVER 派生它。如果是这种情况,请告诉我您是否需要帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-05
      • 1970-01-01
      • 2010-09-20
      • 2021-01-05
      • 1970-01-01
      • 2011-12-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多