Reputation: 41
I am trying to update quantity on hand for all the inventory items that I have whenever I make a purchase or a sale. I have a stored procedure that does the job. It runs along fine, but when I have for example 2000 inventory items, execution of the query takes more than 45 minutes - any ideas?
CREATE PROCEDURE [dbo].[UpdateProducts]
AS
BEGIN
DECLARE @LoopCounter INT , @MaxCode INT,
SELECT @LoopCounter = MIN(ProductId), @MaxCode = MAX(ProductId)
FROM products
WHILE (@LoopCounter IS NOT NULL
AND @LoopCounter <= @MaxCode)
BEGIN
UPDATE Products
SET QuantityOnHand = (SELECT
((SELECT ISNULL(SUM(ISNULL(Qty, 0)), 0)
FROM BILLDETAILS
WHERE Pid = @LoopCounter) -
(SELECT ISNULL(SUM(ISNULL(Qty, 0)), 0)
FROM InvoiceDetails
WHERE Pid = @LoopCounter) -
(SELECT ISNULL(SUM(ISNULL(Qty, 0)), 0)
FROM SalesDetails
WHERE Pid = @LoopCounter))
WHERE ProductId= @LoopCounter
SELECT @LoopCounter = MIN(ProductId)
FROM Products
WHERE ProductId > @LoopCounter
END
END
Upvotes: 0
Views: 98
Reputation: 41
I fiqured out why my query was slow i had a column that stores the last update date & time of each row.and i was updating that column by using a trigger and that affected performance dramatically.
Upvotes: 1
Reputation: 66
Try this
create PROCEDURE [dbo].[UpdateProducts]
as
DECLARE @productIdCursor AS int
DECLARE
countProduct
CURSOR FOR
SELECT productId FROM Products
OPEN countProduct
FETCH NEXT FROM countProduct INTO @productIdCursor
WHILE @@fetch_status = 0
BEGIN
declare @value decimal(18,2)
set @value=(select
(select ISNULL (SUM (isnull (Qty,0)),0) from BILLDETAILS where Pid = @productIdCursor) -
(select ISNULL (SUM (isnull (Qty,0)),0) from InvoiceDetails where Pid = @productIdCursor) -
(select ISNULL (SUM (isnull (Qty,0)),0) from SalesDetails where Pid = @productIdCursor)
from Products where ProductId= @productIdCursor)
update Products
set QuantityOnHand =@value
where ProductId= @productIdCursor
print @value
print @productIdCursor
FETCH NEXT FROM countProduct INTO @productIdCursor
END
CLOSE countProduct
DEALLOCATE countProduct
Just change the type of the varieble "@value" if your need
Upvotes: 0
Reputation: 7666
I don't get why you are using a WHILE
loop to achieve this. You should easily be able to update all products by using JOIN
:
UPDATE p
SET p.QuantityOnHand =
(ISNULL(SUM(ISNULL(b.Qty, 0)), 0) -
ISNULL(SUM(ISNULL(i.Qty, 0)), 0) -
ISNULL(SUM(ISNULL(s.Qty, 0)), 0))
FROM Products p
INNER JOIN BillDetails b ON p.ProductId = b.Pid
INNER JOIN InvoiceDetails i ON p.ProductId = i.Pid
INNER JOIN SalesDetails s ON p.ProductId = s.Pid
Upvotes: 5