1

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

当我从 ASP 调用此查询时,我收到 500 错误,并且在日志中它说我有一个

列名“供应商”无效。

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

消息 207,级别 16,状态 1,第 46 行
无效的列名称“供应商”。

消息 207,级别 16,状态 1,第 46 行
无效的列名称“类型”。

消息 207,级别 16,状态 1,第 46 行
无效的列名称“子类型”。

消息 207,级别 16,状态 1,第 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 实例中工作正常。当我将它导入 2012 时,我将 DB 的兼容性级别从 80 更改为 100。

任何帮助将非常感激。

谢谢,迈克。

4

1 回答 1

1

问题出在查询的 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 中如何正常工作。

于 2013-05-22T03:04:19.790 回答