用 SQL 游标更新,最后有变量

Update with SQL cursor, with variable at the end

我有一个关于用游标更新 SQL table 的问题。对于特定的产品,我知道今天的库存,每天有多少进货,多少出货。现在我需要计算未来几天的预期库存。

以这张图片为例:

所以今天我们有 78 件,不会有任何事情发生。明天35要出去,所以实际库存应该变成43。但是后天57要出去,所以库存需要从43变成-14(43-57)。所以在每一行之后,必须更新库存。

我想我需要一个光标,我已经尝试了几天,但它根本不起作用。

[参见 table]

这是我当前对游标的查询:

BEGIN
DECLARE @date int;
DECLARE @product varchar(max);
DECLARE @current_stock int;
DECLARE @incoming int;
DECLARE @outgoing int;
DECLARE @day_stock int;

DECLARE stock_cursor cursor for
SELECT date, product, current_stock, incoming, outgoing, day_stock FROM stock_table order by date asc

Open stock_cursor;
fetch next from stock_cursor into @date, @product, @current_stock, @incoming, @outgoing, @day_stock
WHILE @@FETCH_STATUS = 0
BEGIN


UPDATE stock_table
SET day_stock = current_stock + incoming - outgoing
WHERE CURRENT OF stock_cursor


fetch next from stock_cursor into @date, @product, @current_stock, @incoming, @outgoing, @day_stock
end
close stock_cursor;
deallocate stock_cursor;
end

首先,它说:'The cursor is READ ONLY.'但是我需要按日期排序,因为日期排序对于更新顺序很重要。

但最重要的是,它不使用最后已知的库存来更新传入和传出的数字以创建新的 day_stock。真的不知道要改什么。

有人可以帮我解决一下或者看看我做错了什么吗?

提前致谢。

不需要游标(很少需要游标 ;-)

您所做的一切似乎只是维持 运行 总数 - 这是数据库可以在睡眠中做的事情!

您可以使用 sum over()

轻松添加 运行 总数

这么说,这不是一个特别好的设计,我会建议一个单独的库存来存储每个产品的当前库存值:-)

create table X ([Date] date, Product uniqueidentifier, CurrentStock int, Incoming int, Outgoing int)

insert into X select '20210306', 'B1A761BF-7897-41D9-AAD8-DF6D8832B877', 78, 0, 0
insert into X select '20210307', 'B1A761BF-7897-41D9-AAD8-DF6D8832B877', 78, 0, 35
insert into X select '20210308', 'B1A761BF-7897-41D9-AAD8-DF6D8832B877', 78, 0, 57
insert into X select '20210309', 'B1A761BF-7897-41D9-AAD8-DF6D8832B877', 78, 0, 14
insert into X select '20210310', 'B1A761BF-7897-41D9-AAD8-DF6D8832B877', 78, 0, 2
insert into X select '20210311', 'B1A761BF-7897-41D9-AAD8-DF6D8832B877', 78, 0, 24
insert into X select '20210312', 'B1A761BF-7897-41D9-AAD8-DF6D8832B877', 78, 0, 24
insert into X select '20210313', 'B1A761BF-7897-41D9-AAD8-DF6D8832B877', 78, 0, 0
insert into X select '20210314', 'B1A761BF-7897-41D9-AAD8-DF6D8832B877', 78, 0, 0
insert into X select '20210315', 'B1A761BF-7897-41D9-AAD8-DF6D8832B877', 78, 0, 53
insert into X select '20210316', 'B1A761BF-7897-41D9-AAD8-DF6D8832B877', 78, 12, 0

不同产品的其他示例数据

insert into X select '20210308', '09334B58-EAB8-4C44-80C6-B87B5E4DDC01', 50, 6, 4
insert into X select '20210309', '09334B58-EAB8-4C44-80C6-B87B5E4DDC01', 50, 0, 1
insert into X select '20210310', '09334B58-EAB8-4C44-80C6-B87B5E4DDC01', 50, 0, 10

select *, 
    currentstock - sum(Outgoing) over(partition by Product order by [Date]) + sum(Incoming) over(partition by Product order by [Date]) DayStock
from X
where product='B1A761BF-7897-41D9-AAD8-DF6D8832B877'
order by [date]

结果

Date       Product                                CurrentStock    Incoming    Outgoing    DayStock
---------- -------------------------------------- ------------ ----------- ----------- -----------
2021-03-06 "B1A761BF-7897-41D9-AAD8-DF6D8832B877"           78           0           0          78
2021-03-07 "B1A761BF-7897-41D9-AAD8-DF6D8832B877"           78           0          35          43
2021-03-08 "B1A761BF-7897-41D9-AAD8-DF6D8832B877"           78           0          57         -14
2021-03-09 "B1A761BF-7897-41D9-AAD8-DF6D8832B877"           78           0          14         -28
2021-03-10 "B1A761BF-7897-41D9-AAD8-DF6D8832B877"           78           0           2         -30
2021-03-11 "B1A761BF-7897-41D9-AAD8-DF6D8832B877"           78           0          24         -54
2021-03-12 "B1A761BF-7897-41D9-AAD8-DF6D8832B877"           78           0          24         -78
2021-03-13 "B1A761BF-7897-41D9-AAD8-DF6D8832B877"           78           0           0         -78
2021-03-14 "B1A761BF-7897-41D9-AAD8-DF6D8832B877"           78           0           0         -78
2021-03-15 "B1A761BF-7897-41D9-AAD8-DF6D8832B877"           78           0          53        -131
2021-03-16 "B1A761BF-7897-41D9-AAD8-DF6D8832B877"           78          12           0        -119