在动态SQL中按别名列名排序?

时间:2015-05-20 07:04:47

标签: sql-server stored-procedures sql-server-2012 sql-order-by dynamic-sql

我的数据库中有一个存储过程。它有动态SQL值,我根据收到的参数选择合适的值。

我在此过程中使用别名列名。使用别名列名称的订单值时出错。以下是我的程序。

ALTER Procedure [dbo].[WP_GetVendorPriceList]
    @ItemType        bit,
    @OrderMode       bit,
    @VendorName      varchar(75),
    @OrderBy         varchar(75)
as
Begin 
    DECLARE @QueryVendorName varchar(max), @QueryAllVendorObs varchar(max), @QueryAllVendorNonObs varchar(max), @WhereQuery varchar(max)

    SET @QueryAllVendorNonObs = ';WITH 
    cteForPrice AS (
    Select ItemID, ItemPartNumber, ItemDescription, CreatedDate, InitialPrice, HP As HPPrice, Apple As ApplePrice, Microsoft As MicrosoftPrice, IBM As IBMPrice
    from (select v.ItemID, VendorName, VendorPrice, ItemPartNumber, ItemDescription, CreatedDate, InitialPrice from VendorItemPricing as v left join MasterItems as m on v.ItemID = m.ItemID)A
    PIVOT(MAX(VendorPrice) FOR VendorName IN (HP,Apple,Microsoft,IBM))P),

    cteForDate AS (SELECT ItemID, HP AS HPUpdatedDate, Apple AS AppleUpdatedDate, Microsoft AS MicrosoftUpdatedDate, IBM AS IBMUpdatedDate 
    FROM (SELECT ItemID, VendorName, UpdatedDate FROM VendorItemPricing) A
    PIVOT(MAX(UpdatedDate) FOR Vendorname IN (HP, Apple, Microsoft, IBM))P),

    cteForObsolete AS (
    SELECT ItemID, HP AS HPObsoleteItem, Apple AS AppleObsoleteItem, Microsoft AS MicrosoftObsoleteItem, IBM AS IBMObsoleteItem
    FROM (SELECT Itemid, Vendorname, CAST(ObsoleteItem AS TINYINT) AS INTColumn FROM VendorItemPricing) A
    PIVOT(MAX(INTColumn) FOR Vendorname IN (HP, Apple, Microsoft, IBM)) P)

    SELECT cteForPrice.ItemID, cteForPrice.ItemPartNumber, cteForPrice.ItemDescription,
        CASE
            WHEN HPObsoleteItem = 0 THEN HPPrice
            WHEN AppleObsoleteItem = 0 THEN ApplePrice
            WHEN (IBMObsoleteItem = 0 OR MicrosoftObsoleteItem = 0) AND ISNULL((IBMPrice), 0) > ISNULL((MicrosoftPrice), 0) THEN IBMPrice
            WHEN (IBMObsoleteItem = 0 OR MicrosoftObsoleteItem = 0) AND ISNULL((MicrosoftPrice), 0) > ISNULL((IBMPrice), 0) THEN MicrosoftPrice
        END AS Price,
        CASE
            WHEN HPObsoleteItem = 0 THEN cteForDate.HPUpdatedDate
            WHEN AppleObsoleteItem = 0 THEN cteForDate.AppleUpdatedDate
            WHEN (IBMObsoleteItem = 0 OR MicrosoftObsoleteItem = 0) AND ISNULL((IBMPrice), 0) > ISNULL((MicrosoftPrice), 0) THEN cteForDate.IBMUpdatedDate
            WHEN (IBMObsoleteItem = 0 OR MicrosoftObsoleteItem = 0) AND ISNULL((MicrosoftPrice), 0) > ISNULL((IBMPrice), 0) THEN cteForDate.MicrosoftUpdatedDate
        END AS UpdatedDate
    FROM cteForPrice
    JOIN cteForObsolete ON cteForPrice.ItemID = cteForObsolete.ItemID
    JOIN cteForDate ON cteForPrice.ItemID = cteForDate.ItemID'

    SET @WhereQuery = ' ORDER BY
                        CASE WHEN '''+ @OrderBy +'''=''Price'' AND '+ cast (@OrderMode as varchar(10)) +'= 0 THEN Price END ASC,
                        CASE WHEN '''+ @OrderBy +'''=''Price'' AND '+ cast (@OrderMode as varchar(10)) +'= 1 THEN Price END DESC'

    IF @VendorName != 'All'
    BEGIN
        exec (@QueryVendorName + @WhereQuery)
    END
    ELSE IF @VendorName = 'All' AND @ItemType = 0
    BEGIN
        exec (@QueryAllVendorNonObs + @WhereQuery)
    END
    ELSE IF @VendorName = 'All' AND @ItemType = 1
    BEGIN
        exec (@QueryAllVendorObs + @WhereQuery)
    END
End

每当我尝试执行此过程时,我都会收到此错误。

  

Msg 207,Level 16,State 1,Line 36
   列名称“价格”无效。
   Msg 207,Level 16,State 1,Line 37
   列名称“价格”无效。

P.S:我只在动态SQL上收到此错误,如果我在没有动态的情况下运行它我没有问题。

1 个答案:

答案 0 :(得分:1)

更改

SET @WhereQuery = ' ORDER BY
                    CASE WHEN '''+ @OrderBy +'''=''Price'' AND '+ cast (@OrderMode as varchar(10)) +'= 0 THEN Price END ASC,
                    CASE WHEN '''+ @OrderBy +'''=''Price'' AND '+ cast (@OrderMode as varchar(10)) +'= 1 THEN Price END DESC'

SET @WhereQuery = ' ORDER BY ' +
                    CASE 
                         WHEN @OrderBy = Price AND @OrderMode = 0 THEN 'Price ASC'
                         WHEN @OrderBy = Price AND @OrderMode = 1 THEN 'Price DESC'
                         ELSE '1'
                    END

SET @WhereQuery = ' ORDER BY ' +
                    CASE 
                         WHEN @OrderBy = Price AND @OrderMode = 0 THEN '4 ASC'
                         WHEN @OrderBy = Price AND @OrderMode = 1 THEN '4 DESC'
                         ELSE '1'
                    END