首先,让我马上声明,我很清楚游标通常是邪恶的,不应该使用——我只是想使用集合,但就是想不出针对这个特定问题的基于集合的解决方案. 如果你告诉我去做一些基于集合的操作,那么我完全赞成,如果你能告诉我你将如何编写这个特定的问题。
基本上,我有很多库存物品需要购买。我想根据最便宜的可用价格进行采购,我知道供应商的价格和他们的库存水平。这里还有一个包装尺寸的问题,如果可能的话,我想按包装尺寸购买。
我已经将我需要购买的东西的清单#needorders
以及供应商的库存水平和价格拉入了#orderedprices
。下面我遍历游标CUR_NEEDED
并创建辅助游标CUR_AVAILABLE
:
DECLARE CUR_NEEDED CURSOR LOCAL SCROLL_LOCKS
FOR
SELECT GoodID
, ConditionID
, QuantityToShip
, OrderStatusID
, RetailerID
, PackSize
FROM #needorders
ORDER BY GoodID
, ConditionID
, PurchaseDate DESC
FOR UPDATE
OPEN CUR_NEEDED
FETCH NEXT FROM CUR_NEEDED INTO @GoodID, @ConditionID, @QuantityToShip, @OrderStatusID, @RetailerID, @PackSize
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE CUR_AVAILABLE CURSOR LOCAL SCROLL_LOCKS
FOR
SELECT SupplierStocklistItemID
, SupplierID
, StockLevel
, SupplierCurrencyID
, CostPrice
FROM #orderedprices
WHERE #orderedprices.GoodID = @GoodID
AND #orderedprices.ConditionID = @ConditionID
AND #orderedprices.StockLevel > 0
ORDER BY #orderedprices.PriceRank
FOR UPDATE
OPEN CUR_AVAILABLE
FETCH NEXT FROM CUR_AVAILABLE INTO @SupplierStocklistItemID, @SupplierID, @StockLevel, @SupplierCurrencyID, @CostPrice
WHILE @@FETCH_STATUS = 0
BEGIN
/*
Buy as many @PackSize as we need to cover how many we require, unless the supplier
only has a certain number, in which case buy that number.
E.g., need 14, pack size 5, 2 suppliers
Supplier A has 11
Supplier B has 40
Buy 9 from Supplier A, with our remaining need being 3.
Buy 5 from supplier B, with our remaining need being -2
*/
--feed rows into #supplierpurchasesbase while @StockLevel > 0
--Figure out how many we need to buy, based upon PackSize
IF @QuantityToShip % @PackSize > 0
BEGIN
SET @Buy = @QuantityToShip - @QuantityToShip % @PackSize + @PackSize
END
ELSE
BEGIN
SET @Buy = @QuantityToShip
END
IF @StockLevel < @Buy
BEGIN
--PRINT 'Supplier only has ' + CAST(@StockLevel AS VARCHAR) + ' for us to buy.'
SET @Buy = @StockLevel
END
INSERT INTO #supplierpurchasesbase (
GoodID
, ConditionID
, SupplierStocklistItemID
, Quantity
, SupplierID
, SupplierCurrencyID
, CostPrice
, RetailerID )
SELECT @GoodID
, @ConditionID
, @SupplierStocklistItemID
, @Buy
, @SupplierID
, @SupplierCurrencyID
, @CostPrice
, @RetailerID
--update @QuantityToShip & the row in CUR_AVAILABLE
IF @StockLevel <= @Buy
BEGIN
UPDATE CUR_AVAILABLE
SET StockLevel = @StockLevel - @Buy
WHERE CURRENT OF CUR_AVAILABLE
SET @QuantityToShip = 0
END
ELSE
BEGIN
UPDATE CUR_AVAILABLE
SET StockLevel = 0
WHERE CURRENT OF CUR_AVAILABLE
SET @QuantityToShip = @QuantityToShip - @Buy
END
--update the stocklevel so we don't see the thing again if we've used it up.
IF @QuantityToShip = 0 --Don't need any more
BEGIN
UPDATE CUR_NEEDED
SET OrderStatusID = @StatusPendingPO
WHERE CURRENT OF CUR_NEEDED
BREAK
END
ELSE --Need more, move next, if we can
FETCH NEXT FROM CUR_AVAILABLE INTO @SupplierStocklistItemID, @SupplierID, @StockLevel, @SupplierCurrencyID, @CostPrice
END
CLOSE CUR_AVAILABLE
DEALLOCATE CUR_AVAILABLE
FETCH NEXT FROM CUR_NEEDED INTO @GoodID, @ConditionID, @QuantityToShip, @OrderStatusID, @RetailerID, @PackSize
END
CLOSE CUR_NEEDED
DEALLOCATE CUR_NEEDED
我遇到的问题是我得到了错误
无效的对象名称“CUR_AVAILABLE”。
当我尝试更新时CURRENT OF CUR_AVAILABLE
。
我尝试将CUR_AVAILABLE
光标定义为@CUR_AVAILABLE
但得到不同的错误。我尝试在 的循环CUR_AVAILABLE
之外定义光标,我尝试不关闭/取消分配光标等。这些似乎都不起作用。WHILE
CUR_NEEDED
在这里我会出错的任何想法(除了不使用集合,除非您有基于集合的解决方案)?