Như lỗi gợi ý, câu lệnh cuối cùng phải là câu lệnh trả về. Không giống như một số ngôn ngữ khác, luồng của IF/ELSE
câu lệnh không được kiểm tra trong quá trình biên dịch, vì vậy SQL Server không biết rằng một trong các nhánh là bắt buộc (thậm chí ELSE
). Vì điều này không được kiểm tra nên không có cách nào để biết liệu hàm có trả về giá trị hay không trừ khi câu lệnh cuối cùng là câu lệnh trả về. Ngay cả một chức năng đơn giản như thế này cũng sẽ thất bại:
CREATE FUNCTION dbo.FlowTest()
RETURNS INT
AS
BEGIN
IF 1 = 1
BEGIN
RETURN 1;
END
ELSE
BEGIN
RETURN 0;
END
END
Giải pháp là chỉ cần loại bỏ ELSE
:
CREATE FUNCTION dbo.FlowTest()
RETURNS INT
AS
BEGIN
IF 1 = 1
BEGIN
RETURN 1;
END
-- ELSE REMOVED
RETURN 0;
END
Hàm sẽ ngừng thực thi khi đạt đến RETURN
đầu tiên , vì vậy ELSE
không bắt buộc.
Vì vậy, hàm của bạn sẽ trở thành:
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
Mặc dù vậy, tôi không thể thấy hàm sẽ hoạt động tốt như thế nào và tại sao bạn lại chuyển ngày dưới dạng varchar nằm ngoài tôi. Bạn không quan tâm đến những thứ được tạo ra từ 23:59:59 đến nửa đêm?
Tôi sẽ có xu hướng cấu trúc lại nó như một hàm được định giá trong bảng nội tuyến và sử dụng ngày tháng đúng cách, ví dụ:
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'
);
Sau đó, bất cứ khi nào bạn gọi dbo.GetBatchReleaseQuantity(...)
chỉ cần gọi (SELECT ReturnValue FROM dbo.GetBatchReleaseQuantityTVP(...))
. Điều này sẽ hoạt động tốt hơn đáng kể và cũng sẽ tránh mọi người chuyển ngày không hợp lệ sang tham số varchar.