Ошибки при попытке использовать параметр функции внутри оператора IF - PullRequest
0 голосов
/ 01 ноября 2018

У меня есть следующее 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 голосов
/ 01 ноября 2018

Используйте функцию ниже

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

    );
0 голосов
/ 01 ноября 2018

Есть несколько проблем с функцией

Во-первых, вы не можете назначить значение по умолчанию для функции, вы не можете использовать IF .. ELSE внутри функции Во-вторых. таблицы Food и OrderFoodRel не JOINed. Вы делаете кросс-соединение здесь

Ему не нравится getdate () в качестве значения по умолчанию, вы можете установить NULL в качестве значения по умолчанию для @EndDate и использовать 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)
0 голосов
/ 01 ноября 2018

Вы не можете использовать процедурную логику внутри 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
...