动态查询中的列名错误无效。适用于SQL Server 2008但不适用于SQL Server 2012

时间:2013-05-21 04:37:08

标签: sql-server-2012 dynamic-sql

我正在从SQL Server 2008(而不是R2)迁移到SQL Server 2012.我已将我的数据库恢复到SQL Server 2012但我在尝试调用某个动态查询时遇到运行时错误。

当我从ASP调用此查询时,我收到500错误,并在日志中显示我有

  

列名称“供应商”无效。

当我直接在SSMS中运行相同的程序时,它告诉我我有以下错误:

  

Msg 207,Level 16,State 1,Line 46
  列名称“供应商”无效。

     

Msg 207,Level 16,State 1,Line 46
  列名称“类型”无效。

     

Msg 207,Level 16,State 1,Line 46
  列名称“SubType”无效。

     

Msg 207,Level 16,State 1,Line 46
  列名称'CustPrice'无效。

这是存储过程中的代码。问题仅发生在@mode = 'Search'

ALTER PROCEDURE [dbo].[spProductSearch]
                @idCompany      int = 0,
                @idBusiness     int = 0,
                @cat            int = 0,
                @subCat         int = 0,
                @idPerson       int = 0,
                @target         nvarchar(99),
                @targetSQL      nvarchar(99),
                @priceLower     money = 0,
                @priceUpper     money = 999999999.99,
                @orderBy        nvarchar(9),
                @grouping       int = 1,
                @inStock        int = 0,
                @isCurrent      int = 0,
                @mode           nvarchar(99)

AS 
Set nocount on

DECLARE         @sql            nvarchar(4000),                                
                @paramlist      nvarchar(4000),
                @orderLit       varchar(99),
                @margin         decimal(9,5)


Select  @margin = margin 
From    Company 
Where   idCompany = @idCompany              

-- Determine the Select Statement

If @mode = 'Consumables'
Begin
    Select @sql = 
        'Select *
            FROM        dbo.PrinterConsumable pc 
            INNER JOIN  dbo.vwProductListAll p 
            ON          pc.consumableID = p.ProductID 
            WHERE       p.idCompany = @idCompany 
            AND         pc.printerID = @target
            AND         p.CustPrice BETWEEN @priceLower AND @priceUpper'
End

If @mode = 'Drill'
Begin
    -- If drilling down through the Desktop subcat, show unique skus for vendorProductID and Supplier
    If @subcat = '1000010'
        Begin
            Select @sql = 
                'Select *
                    FROM        dbo.vwProductListAll P      
                    INNER JOIN
                        (SELECT      vendorProductID, idSupplier, MIN(dealerBuy) AS minDealerBuy
                        FROM           dbo.Product
                        GROUP BY vendorProductID, idSupplier) PS 
                        ON PS.vendorProductID = P.ProductID AND PS.idSupplier = P.idSupplier AND PS.minDealerBuy = P.DealerPrice
                        WHERE       p.idCompany = @idCompany 
                        AND         p.CustPrice BETWEEN @priceLower AND @priceUpper'
        End
    Else
        Begin
            Select @sql = 
                'Select *
                    FROM        dbo.vwProductListAll P      
                    WHERE       p.idCompany = @idCompany 
                    AND         p.CustPrice BETWEEN @priceLower AND @priceUpper'
        End
End

If @mode = 'Favs'
Begin
    Select @sql = 
        'Select *
            FROM        dbo.vwProductListAll p
            INNER JOIN  dbo.ProductFavs pf ON p.idProduct = pf.idProduct
            WHERE       p.idCompany = @idCompany 
            AND         pf.idPerson = @idPerson
            AND         p.CustPrice BETWEEN @priceLower AND @priceUpper'
End

If @mode = 'Search'
Begin
    Select @sql = 
            'SELECT B.businessName                                              As Vendor, 
                PC.cat                                                          As Type, 
                PSC.subCat                                                      As SubType,   
                P.idProduct,
                P.vendorProductID                                               As ProductID, 
                P.description                                                   As ProductDesc, 
                100 * dbo.fnCalcMargin(P.margin, PSC.margin, PC.margin, @margin) As Margin,
                ROUND(CAST(P.dealerBuy + P.dealerBuy * dbo.fnCalcMargin(P.margin, PSC.margin, PC.margin, @margin) AS money), 2) AS CustPrice, 
                CAST(P.rrp - (P.dealerBuy + P.dealerBuy * dbo.fnCalcMargin(P.margin, PSC.margin, PC.margin, @margin)) AS money) AS Saving,
                P.dealerBuy                                                     AS DealerPrice, 
                P.rrp,
                B.idBusiness,
                PC.idCat,
                PSC.idSubCat,
                Case IsNull(P.url, '''')
                When '''' Then 0 Else 1 End as hasLink, 
                Case IsNull(P.imgURL, '''')                 
                When '''' Then 0 Else 1 End as hasImage, 
                Case IsNull(PI.productInfo, '''')
                When '''' Then 0 Else 1 End as hasInfo, 
                Case IsNull(PI.overview, '''')
                When '''' Then 0 Else 1 End as hasOverView, 
                Case IsNull(PI.keyFeatures, '''')
                When '''' Then 0 Else 1 End as hasKeyFeatures, 
                Case IsNull(PI.warrantyInfo, '''')
                When '''' Then 0 Else 1 End as hasWty, 
                P.idSupplier, S.supplierName, S.location, P.inStock, p.due, p.isCurrent,
                P.imgURL, P.imgURL2, P.url, P.pdfLink, P.isBulkFreight, P.isDoubleFreight, P.isImported
            FROM            dbo.Business B      
            INNER JOIN      dbo.Product P           ON B.idBusiness = P.idBusiness
            LEFT OUTER JOIN dbo.ProductInfo PI      ON P.idProduct = PI.idProduct
            INNER JOIN      dbo.Supplier S          ON P.idSupplier = S.idSupplier
            INNER JOIN      dbo.ProductSubCat PSC   ON P.idSubCat = PSC.idSubCat
            INNER JOIN      dbo.ProductCat PC       ON PSC.idCat = PC.idCat
            WHERE           P.idCompany = @idCompany 
            AND             (ROUND(CAST(P.dealerBuy + P.dealerBuy * dbo.fnCalcMargin(P.margin, PSC.margin, PC.margin, @margin) AS money), 2) BETWEEN @priceLower AND @priceUpper)   
            AND             ((p.idProduct = @target) OR (P.vendorProductID = @target) OR (CONTAINS(p.description, @targetSQL)))' 
End

-- Determine Filter
If @mode = 'Drill'
Begin
    If @idBusiness > 0  
        Select @sql = @sql + '  AND idBusiness = @idBusiness '

    If @cat > 0  
        Select @sql = @sql + '  AND idCat = @cat '

    If @subCat > 0  
        Select @sql = @sql + '  AND idSubCat = @subCat '
End

If @inStock = 1
    Select @sql = @sql + ' AND p.instock > 0'

If @isCurrent = 1
    Select @sql = @sql + ' AND p.isCurrent = 1'

-- Determine Sorting
If @orderBy = 'Desc'
    Select @orderLit = 'p.ProductDesc'
Else if @orderBy = 'Price'  
    Select @orderLit = 'p.CustPrice'
Else
    Select @orderLit = 'p.ProductID'

-- Determine Grouping
If @grouping = 1
    Select @sql = @sql + ' ORDER BY p.Vendor, p.Type, p.SubType, ' + @orderLit
Else
    Select @sql = @sql + ' ORDER BY ' + @orderLit

-- Recompile hint to see if it resolves the query timeout issue.  It didn't!
-- Select @sql = @sql + ' OPTION (RECOMPILE);'

-- Setup the Parameter List 
Select @paramList = '@idCompany     int,
                     @idBusiness    int,
                     @cat           int,
                     @subCat        int,
                     @target        nvarchar(99),   
                     @targetSQL     nvarchar(99),
                     @priceLower    money,
                     @priceUpper    money = 999999999.99,
                     @margin        decimal(9,5),
                     @idPerson      int'    

-- Execute the query
EXEC sp_executesql @sql, @paramlist, @idCompany, @idBusiness, @cat, @subCat, @target, @targetSQL, @priceLower, @priceUpper, @margin, @idPerson

IF @@ERROR <> 0 
    RETURN (1)  

 --return success code (0)
RETURN (0)

不确定这是否相关,但此代码最初是用SQL Server 2000编写的。它在我的SQL Server 2008实例中运行正常。我将数据库的兼容级别从80改为100时将其导入2012年。

非常感谢任何帮助。

谢谢, 麦克风。

1 个答案:

答案 0 :(得分:0)

问题原来是查询的Order By部分。

-- Determine Sorting
If @orderBy = 'Desc'
    Select @orderLit = 'p.ProductDesc'
Else if @orderBy = 'Price'  
    Select @orderLit = 'p.CustPrice'
Else
    Select @orderLit = 'p.ProductID'

-- Determine Grouping
If @grouping = 1
    Select @sql = @sql + ' ORDER BY p.Vendor, p.Type, p.SubType, ' + @orderLit
Else
    Select @sql = @sql + ' ORDER BY ' + @orderLit

我从派生列名的前面删除了P.并且查询运行正常,即:

-- Determine Sorting
If @orderBy = 'Desc'
    Select @orderLit = 'ProductDesc'
Else if @orderBy = 'Price'  
    Select @orderLit = 'CustPrice'
Else
    Select @orderLit = 'ProductID'

-- Determine Grouping
If @grouping = 1
    Select @sql = @sql + ' ORDER BY Vendor, Type, SubType, ' + @orderLit
Else
    Select @sql = @sql + ' ORDER BY ' + @orderLit

有趣的是它在SQL2000 - 2008中的工作正常。