1

SQL Server 2008 (R2 ではない) から SQL Server 2012 に移行中です。データベースを SQL Server 2012 に復元しましたが、特定の動的クエリを呼び出そうとするとランタイム エラーが発生します。

ASP からこのクエリを呼び出すと、500 エラーが発生します。ログには、

列名「ベンダー」が無効です。

SSMS で同じ手順を直接実行すると、次のエラーがあることがわかります。

メッセージ 207、レベル 16、状態 1、行 46
列名 'Vendor' が無効です。

メッセージ 207、レベル 16、状態 1、行 46
列名 'Type' が無効です。

メッセージ 207、レベル 16、状態 1、行 46
列名 'SubType' が無効です。

メッセージ 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 に答える