Вставка строк и обновление таблицы без использования курсора SQL

Я пытаюсь создать хранимую процедуру 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 стол с OrderItemId, StockId и количество (20 и 30) для двух использованных партий, а также уменьшить количество запаса в STOCK стол соответственно.

Предполагая, что необходимые транзакции имеются для постоянного ведения таблиц запасов, есть ли способ выполнить вставки и обновления без использования 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, Если это так, дайте мне знать, если вам нужна помощь с этим.

Другие вопросы по тегам