Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Masalah Fungsi Sql Pernyataan terakhir yang disertakan dalam suatu fungsi harus berupa pernyataan kembali

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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara menyimpan nilai desimal di SQL Server?

  2. masukkan ke dalam nilai dengan klausa where

  3. Nilai NULL dikecualikan. Mengapa?

  4. Hapus Padding Saat Mengirim Hasil Kueri dalam Email dari SQL Server (T-SQL)

  5. freeTDS tidak menggunakan konfigurasinya