尝试在IF语句中使用函数参数时出错

时间:2018-11-01 06:06:20

标签: sql-server sql-function

我有以下CREATE FUNCTION

CREATE FUNCTION ufnTotalSales (@StartDate datetime, @EndDate datetime = GETDATE(), @FoodName nvarchar(50) = '')
RETURNS TABLE
AS
    RETURN
    (
        IF @FoodName = '';
        BEGIN
            SELECT f.FoodID, FoodName, (FoodPrice * Quantity) AS TotalSales FROM Food f, OrderFoodRel ofr
            WHERE (Date_Time BETWEEN @StartDate AND @EndDate)
        END

        ELSE
        BEGIN
            SELECT f.FoodID, FoodName, (FoodPrice * Quantity) AS TotalSales FROM Food f, OrderFoodRel ofr
            WHERE (Date_Time BETWEEN @StartDate AND @EndDate) AND @FoodName = FoodName
        END
    );

第一个错误发生在@EndDate datetime = GETDATE(),上面写着Incorrect syntax near '()'。如果用户选择使用默认值,我正在尝试为@EndDate参数分配当前datetime的默认值,但不知何故我报错了。

第二个错误发生在我在IF ... ELSE块(@FoodName@StartDate@EndDate)中使用的所有参数上。它说我Must declare the scalar variable "@..."。这是一个参数,而不是标量变量,如何解决?

此功能的想法是通过两种选择返回食品的总销售额:一个是名称X的食品从某个日期到另一个日期(如果您指定了食品名称)的总销售额;第二个是从一个日期到另一个日期的食品总销售额,而与食品名称无关。

3 个答案:

答案 0 :(得分:1)

您不能在ITVF内部使用过程逻辑,而只能使用某种返回结果集的查询。

参考:https://docs.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql?view=sql-server-2017

以下内容很可能接近您要寻找的内容:

CREATE FUNCTION ufnTotalSales
(
  @StartDate datetime
  , @EndDate datetime
  , @FoodName nvarchar(50)
)
RETURNS TABLE
AS
RETURN
  SELECT f.FoodID, FoodName, (FoodPrice * Quantity) AS TotalSales FROM Food f, OrderFoodRel ofr
  WHERE (Date_Time BETWEEN @StartDate AND coalesce(@EndDate,getdate()))
  and coalesce(@FoodName,'') = ''
  union all
  SELECT f.FoodID, FoodName, (FoodPrice * Quantity) AS TotalSales FROM Food f, OrderFoodRel ofr
  WHERE (Date_Time BETWEEN @StartDate AND coalesce(@EndDate,getdate()))
  AND coalesce(@FoodName,'') = FoodName

答案 1 :(得分:1)

使用以下功能

CREATE FUNCTION ufnTotalSales 
(  @StartDate datetime, 
   @EndDate datetime, 
   @FoodName nvarchar(50)
)
RETURNS TABLE
AS
    RETURN
    (
        SELECT f.FoodID, FoodName, (FoodPrice * Quantity) AS TotalSales 
        FROM Food f
        JOIN OrderFoodRel ofr on f.FoodID = ofr.FoodID
        WHERE (Date_Time BETWEEN @StartDate AND ISNULL(@EndDate,GETDATE())) 
         AND ISNULL(@FoodName,'') = FoodName

    );

答案 2 :(得分:1)

该功能有几个问题

首先,您不能为函数分配默认值,也不能在函数内部使用IF .. ELSE 其次。表FoodOrderFoodRel不是JOINed。您正在这里进行交叉连接

它不喜欢getdate()作为默认值,您可以为@EndDate设置NULL为默认值,并在ISNULL()上使用@EndDate

这将创建函数。我假设这2个表与FoodID

相关
CREATE FUNCTION ufnTotalSales 
(
    @StartDate datetime,  
    @EndDate   datetime     = NULL, 
    @FoodName  nvarchar(50) = ''
)
RETURNS TABLE
AS
    RETURN
    (
        SELECT  f.FoodID, FoodName, (FoodPrice * Quantity) AS TotalSales 
        FROM    Food f
                INNER JOIN OrderFoodRel ofr on  f.FoodID    = ofr.FoodID
        WHERE   Date_Time BETWEEN @StartDate AND ISNULL(@EndDate, GETDATE())
        AND     (
                    @FoodName   = ''
                OR  f.FoodName  = @FoodName
                )
    );
GO

因此,要在输入中使用默认值,您需要使用关键字default

select  *
from    dbo.ufnTotalSales('2018-10-01', default , default)