Sql server 操作相关行的值时,SQL替代游标
我有一个存储库存水平的简单表格。即Sql server 操作相关行的值时,SQL替代游标,sql-server,cursor,Sql Server,Cursor,我有一个存储库存水平的简单表格。即 ID int PK LocationID int StockLevel real 此表中每个位置可能有多行,即: ID | LocationID | StockLevel ---------------------------- 1 | 1 | 100 2 | 1 | 124 3 | 2 | 300 在本例中,看到位置1处存在224个单元并不重要 当我开始降低我使用的位置1的库存水平时 在Loca
ID int PK
LocationID int
StockLevel real
此表中每个位置可能有多行,即:
ID | LocationID | StockLevel
----------------------------
1 | 1 | 100
2 | 1 | 124
3 | 2 | 300
在本例中,看到位置1处存在224个单元并不重要
当我开始降低我使用的位置1的库存水平时
在LocationID为1的所有行上迭代的游标,并使用一些简单的
逻辑决定当前行的可用库存是否满足传入的需求
递减值。如果行有足够的数量满足要求,我将减少行值并跳出光标,然后结束该过程;但是,如果行没有足够的可用数量,我将其值减为零,然后移动到下一行,并使用减少的数量重试
这很简单,效果也不错,但不可避免的问题是:有没有一种表演方式
此RBAR操作没有光标??我试图寻找替代方案,但甚至是措辞
这种操作的搜索条件是痛苦的
提前谢谢
尼克
另外,我以这种格式存储数据,因为每一行还包含其他唯一的列,因此不能简单地为每个位置聚合成一行
pps。请求的游标逻辑,其中“@DecrementStockQuantityBy”是我们需要的数量
要在指定位置将库存水平降低一倍,请执行以下操作:
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 CurrentRowStockStockLevel to Zero
--Reduce @DecrementStockQuantityBy by CurrentRowStockStockLevel
--Repeat until @DecrementStockQuantityBy is zero or end of rows reached
END
FETCH NEXT FROM Cursor
END
希望这足够清楚?如果需要进一步/更好的解释,请告诉我。
谢谢,先生,您是对的,一个简单的更新语句可以帮助您在这种情况下,我仍在试图找到光标的合法用途,或者在我无法用CTE或基于集合的方法解决的情况下 在深入研究您的问题之后,我还将提出另一种解决方案:
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
请包括你的游标逻辑。实际上:我们应该看到游标的定义,它处理的SELECT语句,而不是你如何从中获取值……嗨,Jstead,谢谢你的回答。这个解决方案对我不起作用,因为更新的第二行和后续行应该减少更新量。“@decimentvalue”与上一行成功获取的金额之间的差异。然而,在您的示例中,所有行的递减相等。再次感谢Jstead的帮助。我发现:子查询中不允许递归引用。当我运行这个。有什么想法吗?