2013-02-25 4 views
0

주어진 params를 사용하여 SQL 쿼리를 작성하려고하는데 이상한 오류가 발생하고 그 이유를 알 수 없습니다. 여기 내 SP 및동적 SQL 쿼리 검색

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 '[email protected]+' AND '[email protected]+') ' 
    END 

    IF @CityID > 0 
     SET @SQL += ' AND CityID = '[email protected]+'' 

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

    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. 

이 오류를 설명 할 수있다? 감사!

+0

STATUS 열의 유형은 무엇입니까? – veljasije

+0

그것은 작지만 오류 라인은 IF CityID> 0 SET @SQL + = 'AND CityID ='+ CityID + '' –

답변

1

Cast SQL 문에서 연결하기 전에 @PriceMin, @PriceMax 및 @CityID 값.

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)) 
+0

감사합니다. –

1

Romil의 대답은 당신이 묻는 문제를 해결하지만, 당신이 요청해야하는 동적하지 않는이 쿼리를 변경하는 방법입니다 :

수정 된 SQL 문은 다음에 따라입니다. 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 

나는 성능을 향상시키기 위해 문에 의해 그룹과 함께 가입하기 문에 그 하위 쿼리를 이동하는 더 개선 할 것,하지만 더 DB 지식을 필요로한다.