0

特定のパラメーターを使用して SQL クエリを作成しようとしていますが、奇妙なエラーが発生し、その理由がわかりません。これが私のSPと結果です

ALTER PROCEDURE [dbo].[sp_Photographers_Select_Search]
    @Date varchar(100),
    @PriceMin int,
    @PriceMax int,
    @CityID int

AS
BEGIN
    SET DATEFORMAT DMY
    DECLARE @SQL as varchar(2000)
    SET @SQL = 'SELECT *,
     (SELECT TOP (1) Price FROM  Packages WHERE PhotographerID = Photographers.PhotographerID ORDER BY Price) as PriceMin,
     (SELECT TOP (1) Price FROM  Packages WHERE PhotographerID = Photographers.PhotographerID ORDER BY Price DESC) as PriceMax,
     (SELECT COUNT(GalleryID) FROM Galleries WHERE PhotographerID = Photographers.PhotographerID AND Status = 1) as GalleryCount,
     (SELECT COUNT(CommentID) FROM Comments WHERE ContentID = Photographers.PhotographerID AND Status = 1 AND TypeID = 1) as CommentCount
     FROM Photographers WHERE 1 = 1  '

    IF @PriceMin <> 0 OR @PriceMax <> 0 BEGIN
        SET @SQL = @SQL + ' AND PhotographerID IN(SELECT PhotographerID FROM Packages WHERE Price BETWEEN '+@PriceMin+' AND '+@PriceMax+') '
    END

    IF @CityID > 0
        SET @SQL += ' AND CityID = '+@CityID+'' 

    SET @SQL = @SQL + ' AND  PhotographerID NOT IN (SELECT PhotographerID FROM Appointments WHERE Date = '''+@Date+''')'    

    EXEC (@SQL)
END

EXEC    @return_value = [dbo].[sp_Photographers_Select_Search]
        @Date = N'23.05.2013',
        @PriceMin = 0,
        @PriceMax = 0,
        @CityID = 34

そして、エラーは

Msg 245, Level 16, State 1, Procedure sp_Photographers_Select_Search, Line 23
Conversion failed when converting the varchar value 'SELECT *,
     (SELECT TOP (1) Price FROM  Packages WHERE PhotographerID = Photographers.PhotographerID ORDER BY Price) as PriceMin,
     (SELECT TOP (1) Price FROM  Packages WHERE PhotographerID = Photographers.PhotographerID ORDER BY Price DESC) as PriceMax,
     (SELECT COUNT(GalleryID) FROM Galleries WHERE PhotographerID = Photographers.PhotographerID AND Status = 1) as GalleryCount,
     (SELECT COUNT(CommentID) FROM Comments WHERE ContentID = Photographers.PhotographerID AND Status = 1 AND TypeID = 1) as CommentCount
     FROM Photographers WHERE 1 = 1  ' to data type int.

エラーについて説明できますか?ありがとう!

4

2 に答える 2

1

Romil's answer はあなたが尋ねた問題を解決しますが、あなたが尋ねるべきことは、このクエリを動的に変更する方法です。あなたの DB 構造がわからないので、このクエリを検証する必要がありますが、私が行った WHERE 句の更新により、動的にならずにクエリを実行できるようになります。これにより、パフォーマンスが劇的に向上し、インジェクションの露出が減少し、これらのタイプのクエリを実行するためのより良い方法になります。

ALTER PROCEDURE [dbo].[sp_Photographers_Select_Search]
    @Date       AS VARCHAR(100),
    @PriceMin   AS INT,
    @PriceMax   AS INT,
    @CityID     AS INT

AS
BEGIN
    SET DATEFORMAT DMY
    SELECT  *,
            (SELECT TOP (1) Price FROM Packages WHERE PhotographerID = Photographers.PhotographerID ORDER BY Price) AS PriceMin,
            (SELECT TOP (1) Price FROM Packages WHERE PhotographerID = Photographers.PhotographerID ORDER BY Price DESC) AS PriceMax,
            (SELECT COUNT(GalleryID) FROM Galleries WHERE PhotographerID = Photographers.PhotographerID AND Status = 1) AS GalleryCount,
            (SELECT COUNT(CommentID) FROM Comments WHERE ContentID = Photographers.PhotographerID AND Status = 1 AND TypeID = 1) AS CommentCount
    FROM    Photographers
    WHERE   1 = 1
        AND PhotographerID NOT IN (SELECT PhotographerID FROM Appointments WHERE Date = @Date)
        AND 
        (
            (
                @PriceMin = 0
                AND @PriceMax = 0
            )
            OR  PhotographerID IN (SELECT PhotographerID FROM Packages WHERE Price BETWEEN @PriceMin AND @PriceMax)
        )
        AND 
        (
            @CityID = 0
            OR  CityID = @CityID
        )
END

パフォーマンスを向上させるために、これらのサブクエリを GROUP BY ステートメントと組み合わせた JOIN ステートメントに移動するようにさらに改善しますが、それにはさらに DB の知識が必要です。

于 2013-02-26T07:31:45.937 に答える
1

CastSQLステートメントで連結する前の数値、つまり @PriceMin 、 @PriceMax 、および @CityID 。

変更された sql ステートメントは次のとおりです。

IF @PriceMin <> 0 OR @PriceMax <> 0 
BEGIN
    SET @SQL = @SQL + ' AND PhotographerID IN(SELECT PhotographerID FROM Packages WHERE Price BETWEEN '+ cast(@PriceMin as varchar(10)) 
    +' AND '+ cast(@PriceMax as varchar(10)) +') '
END

IF @CityID > 0
   SET @SQL += ' AND CityID = '+ cast(@CityID as varchar(10) )
于 2013-02-25T13:07:18.357 に答える