据我了解,使用游标dynamic
将反映对基表所做的任何更改。为什么在以下示例中不会出现这种情况?
我用一个表变量和一个具有相同结果的实际表尝试了这个。如果循环开始后的行@@fetch_status
未注释,我会得到我期望的结果。
declare @BalanceTable table
(
LineId int not null identity(1, 1),
Qty int not null,
Price money not null
)
insert into @BalanceTable (Qty, Price) values (3000, 1)
insert into @BalanceTable (Qty, Price) values (40, 2)
insert into @BalanceTable (Qty, Price) values (1, 1)
insert into @BalanceTable (Qty, Price) values (2000, 1)
insert into @BalanceTable (Qty, Price) values (4047, 2)
insert into @BalanceTable (Qty, Price) values (-3000, 1)
insert into @BalanceTable (Qty, Price) values (-38, 2)
insert into @BalanceTable (Qty, Price) values (3000, 1)
declare BalanceTable cursor
dynamic for
select LineId, Qty, Price
from @BalanceTable
order by LineId
declare @LineId int
declare @Qty int
declare @Price money
open BalanceTable
fetch next from BalanceTable into @LineId, @Qty, @Price
while @@fetch_status = 0
begin
-- select @Qty = Qty, @Price = Price from @BalanceTable where LineId = @LineId
declare @SearchLessZero bit
set @SearchLessZero = case when @Qty > 0 then 1 else 0 end
declare @OffsetLineId int
declare @OffsetQty int
set @OffsetLineId = -1
while @Qty > 0 and @OffsetLineId is not null
begin
select @OffsetLineId = min(LineId)
from @BalanceTable
where LineId > @LineId and Price = @Price and
((@SearchLessZero = 1 and Qty < 0) or (@SearchLessZero = 0 and Qty > 0))
if @OffsetLineId is not null
begin
select @OffsetQty = Qty
from @BalanceTable
where LineId = @OffsetLineId
if @Qty > -@OffsetQty
begin
set @Qty = @Qty + @OffsetQty
set @OffsetQty = 0
end
else
begin
set @OffsetQty = @OffsetQty + @Qty
set @Qty = 0
end
update @BalanceTable set Qty = @OffsetQty where LineId = @OffsetLineId
end
end
update @BalanceTable set Qty = @Qty where LineId = @LineId
fetch next from BalanceTable into @LineId, @Qty, @Price
end
close BalanceTable
deallocate BalanceTable
select *
from @BalanceTable
order by LineId