sql >> Databáze >  >> RDS >> Sqlserver

Problém s funkcí SQL Posledním příkazem obsaženým ve funkci musí být příkaz return

Jak chyba naznačuje, poslední příkaz musí být příkaz return. Na rozdíl od některých jiných jazyků tok IF/ELSE příkaz není během kompilace kontrolován, takže SQL Server neví, že jedna z větví je povinná (dokonce i ELSE ). Protože toto není zaškrtnuto, neexistuje způsob, jak zjistit, zda funkce vrátí hodnotu, pokud poslední příkaz není příkaz return. I taková jednoduchá funkce selže:

CREATE FUNCTION dbo.FlowTest()
RETURNS INT
AS
BEGIN
    IF 1 = 1
    BEGIN
        RETURN 1;
    END
    ELSE
    BEGIN
        RETURN 0;
    END
END

Řešením je jednoduše odstranit ELSE :

CREATE FUNCTION dbo.FlowTest()
RETURNS INT
AS
BEGIN
    IF 1 = 1
    BEGIN
        RETURN 1;
    END
    -- ELSE REMOVED
    RETURN 0;

END

Funkce zastaví provádění, když if dosáhne prvního RETURN , takže ELSE stejně není vyžadováno.

Vaše funkce by se tedy stala:

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

Nevidím, jak bude funkce fungovat dobře a proč předáváte datum jako varchar, je mimo mě. Nezajímají vás věci, které byly vytvořeny mezi 23:59:59 a půlnocí?

Přikláněl bych se k tomu, abych to přefaktoroval jako funkci s inline tabulkou a správně používal data, např.

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'
);

Potom kdykoli zavoláte dbo.GetBatchReleaseQuantity(...) jednoduše zavolejte (SELECT ReturnValue FROM dbo.GetBatchReleaseQuantityTVP(...)) . To bude fungovat výrazně lépe a také se vyhnete tomu, že lidé budou zadávat neplatná data do parametru varchar.



  1. Trvalé datum v databázi se nerovná datu načtení

  2. Jak vrátit pouze datum z datového typu SQL Server DateTime

  3. Průvodce nasazením TimescaleDB s Dockerem

  4. Potřebujete pomoc s unpivot v mysql s více sloupci data