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

Errors while Trying to Use a Function Parameter inside an IF Statement

我有以下 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 "@..."。它是一个参数而不是标量变量,我该如何解决这个问题?

这个函数的想法是 return 食品的总销售额有两个选项:一个是名称为 X 的食品从一个日期到另一个日期的总销售额,如果您指定食品名称;两个是从一个日期到另一个日期的食品总销售额,不考虑食品名称。

您不能在 ITVF 中使用过程逻辑,而只能使用某种查询,returns 一个结果集。

参考: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

使用下面的函数

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

    );

函数有几个问题

首先,你不能给函数赋默认值你不能在函数内部使用 IF .. ELSE 第二。表 FoodOrderFoodRel 不是 JOINed。您正在此处进行交叉连接

它不喜欢 getdate() 作为默认值,您可以将 NULL 设置为 @EndDate 的默认值并在 @EndDate

上使用 ISNULL()

这是创建函数。我假设这 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)