Seperti yang disarankan oleh kesalahan, pernyataan terakhir harus berupa pernyataan kembali. Tidak seperti beberapa bahasa lain, aliran IF/ELSE
pernyataan tidak dicentang selama kompilasi, jadi SQL Server tidak mengetahui bahwa salah satu cabang adalah wajib (bahkan ELSE
). Karena ini tidak dicentang, tidak ada cara untuk mengetahui apakah fungsi akan mengembalikan nilai kecuali pernyataan terakhir adalah pernyataan pengembalian. Bahkan fungsi sederhana seperti ini akan gagal:
CREATE FUNCTION dbo.FlowTest()
RETURNS INT
AS
BEGIN
IF 1 = 1
BEGIN
RETURN 1;
END
ELSE
BEGIN
RETURN 0;
END
END
Solusinya adalah dengan menghapus ELSE
:
CREATE FUNCTION dbo.FlowTest()
RETURNS INT
AS
BEGIN
IF 1 = 1
BEGIN
RETURN 1;
END
-- ELSE REMOVED
RETURN 0;
END
Fungsi akan menghentikan eksekusi ketika jika mencapai RETURN
pertama , jadi ELSE
tetap tidak diperlukan.
Jadi fungsi Anda akan menjadi:
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
Saya tidak dapat melihat bagaimana fungsinya akan berjalan dengan baik, dan mengapa Anda melewatkan tanggal sebagai varchar berada di luar jangkauan saya. Apakah Anda tidak peduli dengan hal-hal yang diciptakan antara 23:59:59 dan tengah malam?
Saya akan cenderung untuk memfaktorkan ulang ini sebagai fungsi bernilai tabel sebaris, dan menggunakan tanggal dengan benar, mis.
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'
);
Kemudian kapan pun Anda akan memanggil dbo.GetBatchReleaseQuantity(...)
cukup panggil (SELECT ReturnValue FROM dbo.GetBatchReleaseQuantityTVP(...))
. Ini akan berkinerja lebih baik secara signifikan, dan juga akan menghindari orang yang melewatkan tanggal yang tidak valid ke parameter varchar.