Reputation: 15
So I have some code which drops and re-creates a table each time, then uses a cursor to go through and calculate a running total of stock amounts. The code for the cursor is as below (table names obscured):
DECLARE @Cust_Name nvarchar(250),
@Cust_Postcode nvarchar(50),
@MatchCode_Product nvarchar(50),
--@Stock int,
@DateKey nvarchar(8),
@Ordered int
DECLARE StockCursor CURSOR
LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR
SELECT
Cust_Name, Cust_Postcode, MatchCode_Product, DateKey
FROM
WRK_TFT_DEPOT_STOCK
WHERE
Cust_Name NOT LIKE {redacted}
OPEN StockCursor
FETCH NEXT FROM StockCursor INTO @Cust_Name, @Cust_Postcode, @MatchCode_Product, @DateKey
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE
WRK_TFT_DEPOT_STOCK
SET
Ordered = isnull((
SELECT
sum(cast(MO.Quantity as int))
FROM
{redacted }DE
INNER JOIN {redacted} MO
ON DE.Order_No = MO.Order_No
WHERE
DE.Cust_Name = @Cust_Name
AND
DE.Cust_Postcode = @Cust_Postcode
AND
MatchCode_Product = @MatchCode_Product
AND
CAST(Year(DE.Delivery_Date) AS VARCHAR) + RIGHT('0' + CAST(Month(DE.Delivery_Date) AS VARCHAR), 2) +
RIGHT('0' + CAST(Day(DE.Delivery_Date) AS VARCHAR), 2) <= @DateKey
AND DE.Cust_Name NOT LIKE {redacted}
),0)
WHERE
Cust_Name = @Cust_Name
AND
Cust_Postcode = @Cust_Postcode
AND
MatchCode_Product = @MatchCode_Product
AND
DateKey = @DateKey
FETCH NEXT FROM StockCursor INTO @Cust_Name, @Cust_Postcode, @MatchCode_Product, @DateKey
END
CLOSE StockCursor
DEALLOCATE StockCursor
UPDATE
WRK_TFT_DEPOT_STOCK
SET
Stock = StartStock + Ordered
The code works fine but my issue with it is that it takes ages to run, and the time it takes to run is increasing over time as I'm loading daily data into the source tables.
Would anyone be able to help me out with re-writing this more efficiently? From looking around it looks like windowed functions would help a lot but I'm not familiar with them.
The column 'Stock' is the running total, 'StartStock' is the initial amount and 'Ordered' is what we need to add when it comes in.
Upvotes: 0
Views: 563
Reputation: 3591
An example with rows unbounded preceding:
SELECT TOP 1000 [Dato]
,[Department]
,[Amount]
,runningtotal = SUM(amount) over(order by dato ROWS UNBOUNDED PRECEDING)
FROM [LegOgSpass].[dbo].[amounts]
Result
Upvotes: 1