Както подсказва грешката, последният оператор трябва да бъде оператор за връщане. За разлика от някои други езици потокът на IF/ELSE
изразът не се проверява по време на компилация, така че SQL Server не знае, че един от клоновете е задължителен (дори ELSE
). Тъй като това не е отметнато, няма начин да разберете дали функцията ще върне стойност, освен ако последният оператор не е оператор за връщане. Дори проста функция като тази ще се провали:
CREATE FUNCTION dbo.FlowTest()
RETURNS INT
AS
BEGIN
IF 1 = 1
BEGIN
RETURN 1;
END
ELSE
BEGIN
RETURN 0;
END
END
Решението е просто да премахнете ELSE
:
CREATE FUNCTION dbo.FlowTest()
RETURNS INT
AS
BEGIN
IF 1 = 1
BEGIN
RETURN 1;
END
-- ELSE REMOVED
RETURN 0;
END
Функцията ще спре изпълнението, когато if достигне първия RETURN
, така че ELSE
така или иначе не се изисква.
Така че вашата функция ще стане:
ALTER FUNCTION [dbo].[GetBatchReleaseQuantity]
(
@i_LocationID VARCHAR(50),
@i_ProductID INT,
@i_StartDate VARCHAR(50),
@i_EndDate VARCHAR(50),
@i_ProductInFlow int
)
RETURNS numeric(18,3)
--WITH ENCRYPTION
AS
BEGIN
IF (@i_ProductInFlow ='2')
BEGIN
RETURN (SElECT ISNULL( SUM( BatchReleaseQuantity),0.00)
FROM BatchReleaseDetails BRD
LEFT OUTER JOIN BatchRelease BR
ON BR.BatchReleaseID=BRD.BatchReleaseID
WHERE ProductId = @i_ProductID
AND LocationID = @i_LocationID
AND BRD.CreatedOn >= CONVERT(DATETIME, @i_StartDate+' 00:00:00')
AND BRD.CreatedOn <= CONVERT(DATETIME,@i_EndDate + ' 23:59:59')
)
END
RETURN ( SELECT ISNULL( SUM( AcceptedQuantity),0.00)
FROM GoodsReceivedNoteDetail GRND
LEFT OUTER JOIN GoodsReceivedNote GRN
ON [email protected]_LocationID
WHERE ProductId = @i_ProductID
AND GRN.LocationID = @i_LocationID
AND GRND.CreatedOn >= CONVERT(DATETIME, @i_StartDate+' 00:00:00')
AND GRND.CreatedOn <= CONVERT(DATETIME, @i_EndDate+' 23:59:59')
)
END
END
Не мога да видя как функцията ще работи добре обаче и защо предавате дата като varchar, не мога да разбера. Не ви ли интересуват нещата, които са създадени между 23:59:59 и полунощ?
Бих бил склонен да преработя това като вградена функция с таблични стойности и да използвам датите правилно, напр.
CREATE FUNCTION [dbo].[GetBatchReleaseQuantityTVP]
(
@i_LocationID VARCHAR(50),
@i_ProductID INT,
@i_StartDate DATE,
@i_EndDate DATE,
@i_ProductInFlow int
)
RETURNS TABLE
--WITH ENCRYPTION
AS
RETURN
( SElECT ReturnValue = ISNULL( SUM( BatchReleaseQuantity),0.00)
FROM BatchReleaseDetails BRD
LEFT OUTER JOIN BatchRelease BR
ON BR.BatchReleaseID=BRD.BatchReleaseID
WHERE ProductId = @i_ProductID
AND LocationID = @i_LocationID
AND BRD.CreatedOn >= @i_StartDate
AND BRD.CreatedOn < DATEADD(DAY, 1, @i_EndDate)
AND @i_ProductInFlow ='2'
UNION ALL
SELECT ISNULL(SUM( AcceptedQuantity),0.00)
FROM GoodsReceivedNoteDetail GRND
LEFT OUTER JOIN GoodsReceivedNote GRN
ON [email protected]_LocationID
WHERE ProductId = @i_ProductID
AND GRN.LocationID = @i_LocationID
AND GRND.CreatedOn >= @i_StartDate
AND GRND.CreatedOn < DATEADD(DAY, 1, @i_EndDate)
AND ISNULL(@i_ProductInFlow, '') != '2'
);
Тогава всеки път, когато извикате dbo.GetBatchReleaseQuantity(...)
просто извикайте (SELECT ReturnValue FROM dbo.GetBatchReleaseQuantityTVP(...))
. Това ще работи значително по-добре и също така ще избегне хората да подават невалидни дати към параметър varchar.