I use SQL Server 2008 . I try to Make an report and need to calculate a new Column about each row of my table . I write this function :
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date, ,>
-- Description: <Description, ,>
-- =============================================
ALTER FUNCTION [dbo].[fn_CalcProductStock]
(
@ProductID INT = NULL ,
@ToDate DATETIME = NULL ,
@FinYear INT = NULL ,
@InventoryID INT = NULL
)
RETURNS FLOAT
AS
BEGIN
DECLARE @stock FLOAT
SET @stock = ISNULL(( SELECT SUM(IDI.InvDocItemNumbers)
FROM InvDocItem IDI
LEFT OUTER JOIN InvDoc ID ON IDI.CenterID = ID.CenterID
AND IDI.InvDocID = ID.InvDocID
WHERE IDI.ProductID = @ProductID
AND ID.FinYearID = @FinYear
AND ( ID.InventoryID = @InventoryID
OR @InventoryID IS NULL
)
AND ID.InvDocDate < @ToDate
AND ( ID.InvTransTypeID = 1
OR ID.InvTransTypeID = 4
OR ID.InvTransTypeID = 6
OR ID.InvTransTypeID = 13
OR ID.InvTransTypeID = 9
)
), 0)
- ISNULL(( SELECT SUM(II.InvoiceItemNumbers)
FROM InvoiceItem II
LEFT OUTER JOIN Invoice I ON ( II.CenterID = I.CenterID
AND II.InvoiceID = I.InvoiceID
)
WHERE II.ProductID = @ProductID
AND I.FinYearId = @FinYear
AND I.InvoiceDate < @ToDate
AND ( I.InventoryID = @InventoryID
OR @InventoryID IS NULL
) --Tehran:1 Tehrantakh:101 Mashhad:21 Tabriz:6
AND ( I.InvoiceType = 1
OR I.InvoiceType = 3
)
), 0)
+ ISNULL(( SELECT SUM(II.InvoiceItemNumbers)
FROM InvoiceItem II
LEFT OUTER JOIN Invoice I ON II.CenterID = I.CenterID
AND II.InvoiceID = I.InvoiceID
WHERE II.ProductID = @ProductID
AND I.FinYearId = @FinYear
AND I.InvoiceDate < @ToDate
AND ( I.InventoryID = @InventoryID
OR @InventoryID IS NULL
)
AND ( I.InvoiceType = 2
OR I.InvoiceType = 4
)
), 0)
- ISNULL(( SELECT SUM(IDI.InvDocItemNumbers)
FROM InvDocItem IDI
LEFT OUTER JOIN InvDoc ID ON IDI.CenterID = ID.CenterID
AND IDI.InvDocID = ID.InvDocID
WHERE IDI.ProductID = @ProductID
AND ID.InvTransTypeID = 3
AND ID.FinYearID = @FinYear
AND ( ID.InventoryID = @InventoryID
OR @InventoryID IS NULL
)
AND ID.InvDocDate < @ToDate
), 0)
-- Return the result of the function
RETURN @stock
END
also I try to use this fonction in this case :
SELECT Prdct.InventoryID ,
Prdct.ProductID ,
( dbo.fn_CalcProductStock(Prdct.ProductID, '2014-04-29', 92, 101) )
FROM ProductInv AS Prdct
This have true Calculation Result , but takes long time Like as 40 mins ...!!! for 3000 Products
How i can Make it's Performance better ?
InventoryId.FinYearandToDatewill require a value to return any results. The positioning of the conditions forProductIdmeans that the joins are actuallyINNER JOINs - if you don't supply a value, you also get no results (becausenulldoes not equalnull). Your query seems to be getting a quantity of items, but to meItemNumberwould be essentially a key - is this just an ambiguously named variable, or is it a count?