TSQL无需Cursor实现滚动库存计算 解决游标大数据处理性能问题
问题解决实现方案
完全可以通过原生TSQL实现该需求,使用SQL Server 2012及以上版本支持的窗口聚合函数即可,性能相比游标会有数量级提升,完全适配大数据量场景。
核心逻辑说明
按ID分区后,NewInventory的计算可以等价转换为:分区首行的初始库存 + 从分区首行到当前行所有(入库-出库)的累计差值,和你给出的计算规则完全匹配。
查询实现代码
假设你的业务表名为InventoryRecords,查询语句如下:
SELECT ID, Item, Inventory, [Projected Shipment], Receipt, LinkDate, -- 按规则计算NewInventory FIRST_VALUE(Inventory) OVER ( PARTITION BY ID ORDER BY LinkDate ASC ) + SUM(Receipt - [Projected Shipment]) OVER ( PARTITION BY ID ORDER BY LinkDate ASC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS NewInventory FROM InventoryRecords ORDER BY ID, LinkDate;
执行结果和你给出的示例数据完全一致。
原表更新实现代码
如果你需要将计算结果更新到原表的NewInventory字段,可使用CTE配合更新实现,无需游标:
WITH CalcResult AS ( SELECT NewInventory AS OldValue, FIRST_VALUE(Inventory) OVER ( PARTITION BY ID ORDER BY LinkDate ASC ) + SUM(Receipt - [Projected Shipment]) OVER ( PARTITION BY ID ORDER BY LinkDate ASC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS CalculatedValue FROM InventoryRecords ) UPDATE CalcResult SET OldValue = CalculatedValue;
性能优化建议
建议给业务表创建联合覆盖索引,可完全避免排序操作,实现最优性能:
CREATE NONCLUSTERED INDEX IX_InventoryRecords_ID_LinkDate ON InventoryRecords (ID, LinkDate) INCLUDE (Inventory, Receipt, [Projected Shipment], NewInventory);
如果使用的是SQL Server 2008及更低版本,不支持窗口函数的ORDER BY子句,可以使用递归CTE实现该逻辑,性能依然远高于游标。
内容的提问来源于stack exchange,提问作者user1941025
相关产品推荐
相关产品推荐

