开发者

SQL Alternative to Cursor when Manipulating values of related rows

I have a simple table that stores stock levels. ie.

ID int PK
LocationID int
StockLevel real

There could be multiple rows in this table for each location ie:

ID | LocationID | StockLevel
----------------------------
1  |      1     | 100
2  |      1     | 124
3  |      2     | 300

In this example its trivial to see that 224 units exist at location 1.

When I come to decrement the stock level at location 1 I am using a cursor to iterate over all rows at where LocationID is 1 and using some simple logic decide whether the stock available at the current row will satisfy the passed in decrement value. If the row has sufficient quantity to satisfy the requirement I decrement the rows value and break out of the cursor, and end the procedure, however if the row doesnt have sufficient quantity available I decrement its value to zero and move to the next row and try again (with the reduced quantity)

Its quite simple and works ok, but the inevitable question is: Is there a way of performing this RBAR operation without a cursor?? I have attempted to search for alternatives but even wording the search criteria for such an operation is painful!

Thanks in advance Nick

ps. I am storing data in this format because each row also contains other columns that are unique, and hence cant simply be aggregated into one row for each location.

pps. Cursor Logic as requested (where '@DecrementStockQuantityBy' is the quantity that we need to reduce the stock level by at the specified location):

WHILE @@FETCH_STATUS = 0
BEGIN

   IF CurrentRowStockStockLevel >= @DecrementStockQuantityBy
   BEGIN

          --This row has enough stock to satisfy decrement request
        --Update Quantity on the Current Row by @DecrementStockQuantityBy   
          --End Procedure       
          BREAK

   END

   IF CurrentRowStockStockLevel < @DecrementStockQuantityBy
   BEGIN

         --Update开发者_StackOverflow CurrentRowStockStockLevel to Zero
         --Reduce @DecrementStockQuantityBy by CurrentRowStockStockLevel
         --Repeat until @DecrementStockQuantityBy is zero or end of rows reached

   END

   FETCH NEXT FROM Cursor

END

Hope this is clear enough? Let me know if further/better explanation is required. Thanks


You are correct sir a simple update statement can help you in this scenario I'm still trying to find a legitimate use for a cursor or while that I can't solve with CTE or set based.

After looking a little deeper into your question I will also propose an alternate solution:

Declare @LocationValue int = 1,@decimentvalue int = 20


with temp (id,StockLevel,remaining) as (
select top 1 id, Case when StockLevel - @decimentvalue >0 then
           StockLevel = StockLevel - @decimentvalue 
         else 
           StockLevel = 0
         end,  @decimentvalue - StockLevel
from simpleTable st
where st.LocationID  = @LocationValue
union all 
select top 1 id, Case when StockLevel - t.remaining >0 then
           StockLevel = StockLevel -t.remaining 
         else 
           StockLevel = 0
         end,  t.remaining - StockLevel
from simpleTable st
where st.LocationID  = @LocationValue
and exists (select remaining from temp t
            where st.id <> t.id
            group by t.id
            having min(remaining ) >0) )

update st
set st.StockLevel = t.StockLevel
from simpleTable st
inner join temp t on t.id = st.id
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜