Неверный синтаксис рядом с ключевым словом 'IF' с использованием результата WITH - PullRequest
0 голосов
/ 05 июня 2018

Я пытаюсь выставить IF .. ELSE, как показано ниже, но получаю сообщение об ошибке.

По сути, если параметр IncludeInvalidSales не установлен, я хочу, чтобы результат подзапроса был отфильтрован дополнительно.

"Неверный синтаксис рядом с ключевым словом 'IF'.

CREATE PROCEDURE [dbo].[ListSalesOrders]
    @OrderId char(36),
    @Top int,
    @IncludeInvalidSales bit
AS
    WITH Temp AS    (SELECT TOP (@Top) Id, OrderId, CustomerName, SalesStatus
                    FROM [dbo].[SalesInventory]
                    WHERE OrderId = @OrderId
                    ORDER BY [Id] DESC)


    IF @IncludeInvalidSales = 1
        BEGIN
            SELECT OrderId, CustomerName, SalesStatus
            FROM Temp
            ORDER BY [Id] ASC
        END     
    ELSE
        BEGIN         
            SELECT OrderId, CustomerName, SalesStatus
            FROM Temp
                    WHERE SalesStatus NOT LIKE '%invalid%'
            ORDER BY [Id] ASC
        END
RETURN 0

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

Альтернатива предоставленному ответу @marcguillot, который оставляет вам одно окончательное утверждение SELECT, а не два.

CREATE PROCEDURE [dbo].[ListSalesOrders]
    @OrderId char(36),
    @Top int,
    @IncludeInvalidSales bit
AS
    WITH Temp AS (SELECT TOP (@Top) Id, OrderId, CustomerName, SalesStatus
                    FROM [dbo].[SalesInventory]
                    WHERE OrderId = @OrderId
                    ORDER BY [Id] DESC)
    SELECT OrderId, CustomerName, SalesStatus
    FROM Temp
    WHERE
        @IncludeInvalidSales = 1 
        OR SalesStatus NOT LIKE '%invalid%'
    ORDER BY [Id] ASC
RETURN 0

EDIT

Случай, когда верхние @Top ордера включают один или несколько недействительных ордеров, оставит вам потенциально меньше записей, чем вы хотите, когдаВы отфильтровываете недействительные.Этого можно избежать, переместив логику фильтра в CTE.

CREATE PROCEDURE [dbo].[ListSalesOrders]
    @OrderId char(36),
    @Top int,
    @IncludeInvalidSales bit
AS
    WITH Temp AS 
        (SELECT TOP (@Top) Id, OrderId, CustomerName, SalesStatus
         FROM [dbo].[SalesInventory]
         WHERE OrderId = @OrderId
             AND (@IncludeInvalidSales = 1 
                  OR SalesStatus NOT LIKE '%invalid%')
         ORDER BY [Id] DESC)
    SELECT OrderId, CustomerName, SalesStatus
    FROM Temp
    ORDER BY [Id] ASC
RETURN 0
0 голосов
/ 05 июня 2018

За общим табличным выражением можно следовать только с одним оператором INSERT, UPDATE или DELETE, но не с конструкцией IF .. ELSE.

За CTE должен следовать один оператор SELECT, INSERT, UPDATE или DELETE, который ссылается на некоторые или все столбцы CTE.CTE также может быть указан в операторе CREATE VIEW как часть определяющего оператора SELECT представления.https://docs.microsoft.com/en-us/sql/t-sql/queries/with-common-table-expression-transact-sql?view=sql-server-2017

Итак, если вы все еще хотите использовать свой CTE, я бы изменил ваш код на:

CREATE PROCEDURE [dbo].[ListSalesOrders]
    @OrderId char(36),
    @Top int,
    @IncludeInvalidSales bit
AS
    IF @IncludeInvalidSales = 1
        BEGIN
            WITH Temp AS    (SELECT TOP (@Top) Id, OrderId, CustomerName, SalesStatus
                            FROM [dbo].[SalesInventory]
                            WHERE OrderId = @OrderId
                            ORDER BY [Id] DESC)

            SELECT OrderId, CustomerName, SalesStatus
            FROM Temp
            ORDER BY [Id] ASC
        END     
    ELSE
        BEGIN         
            WITH Temp AS    (SELECT TOP (@Top) Id, OrderId, CustomerName, SalesStatus
                            FROM [dbo].[SalesInventory]
                            WHERE OrderId = @OrderId
                            ORDER BY [Id] DESC)

            SELECT OrderId, CustomerName, SalesStatus
            FROM Temp
                    WHERE SalesStatus NOT LIKE '%invalid%'
            ORDER BY [Id] ASC
        END
RETURN 0

Вы также можете заменить свой CTE табличной переменной, так чтоВы все еще можете использовать свою логику, как задумано.

CREATE PROCEDURE [dbo].[ListSalesOrders]
    @OrderId char(36),
    @Top int,
    @IncludeInvalidSales bit
AS
    DECLARE @Temp TABLE (Id integer, OrderId integer, CustomerName nvarchar(255), SalesStatus integer)

    INSERT INTO @Temp (Id, OrderId, CustomerName, SalesStatus)
           SELECT TOP (@Top) Id, OrderId, CustomerName, SalesStatus
           FROM [dbo].[SalesInventory]
           WHERE OrderId = @OrderId
           ORDER BY [Id] DESC)

    IF @IncludeInvalidSales = 1
        BEGIN  
            SELECT OrderId, CustomerName, SalesStatus
            FROM @Temp
            ORDER BY [Id] ASC
        END     
    ELSE
        BEGIN             
            SELECT OrderId, CustomerName, SalesStatus
            FROM @Temp
            WHERE SalesStatus NOT LIKE '%invalid%'
            ORDER BY [Id] ASC
        END
RETURN 0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...