2

ASP에서 나는 사용자가 선택에 따라 페이지에 표시된 데이터를 필터링 할 수있는 몇 가지 드롭 다운을 설정했습니다.where 절에서 조건을 최적화하는 SQL

이 드롭 다운은 데이터 그룹, 예를 들어 Year 11과 같은 주제, 예를 들어 영어, 교육 그룹 및 하위 그룹에 대한 것입니다.

데이터 수집, 연도 및 주제는 모두 선택해야하지만 교육 그룹 및 하위 그룹은 선택 취소 (모두 선택), 개별 선택 또는 둘 다 선택할 수 있습니다.

SQL 저장 프로 시저의 내 where 절이 이제 하위 그룹 아래의 많은 옵션 때문에 커집니다. 다음은 하위 그룹을 선택하지 않거나 Girls 하위 그룹을 선택하거나 Boys 하위 그룹을 선택한 두 가지 옵션입니다. 이보다 더 많은 것들이 있지만 간략하게하기 위해 나는 게시 한 것을 제한했습니다.

내 질문에 어떤 식 으로든이 코드를 최적화 할 수 있습니까? 아니면 가장 간결합니까? 더 많은 예제가 필요하면 알려 주시면 포스트에 추가하겠습니다.

답변

1

더 많은 기준을 얻는다면, 제공되는 항목에 따라 다른 쿼리를 작성하는 동적 SQL을 조사하는 것이 좋습니다.

Where 
    [StuYear] = @StuYear And 
    [DataCollection] = @DataCollection And 
    [Name] = @SubjectName And (
     @TeachingGroup = 'Select All' Or 
     [TeachingGroup] = @TeachingGroup 
    ) And (
     @SubGroup = 'Select All' Or 
     Gender = Case 
       When @SubGroup = 'GenF' Then 'F' 
       When @SubGroup = 'GenM' Then 'M' 
      End 
    ) 

동적 SQL 예를

:

또한, 매우 표준 연습 그러나, 이것은 당신이 무엇을의 간단한 버전이

을 '전체 선택'을 의미하는 '널'통과하는 것

Declare 
    @params nvarchar(max) = ' 
@StuYear int, 
@DataCollection varchar(30), 
@SubjectName varchar(30), 
@TeachingGroup varchar(30), 
@SubGroup varchar(30)', --replace with your definitions 
    @sql nvarchar(max) = ' 
Select 
    xxx 
from 
    xxx 
Where 
    [StuYear] = @StuYear And 
    [DataCollection] = @DataCollection And 
    [Name] = @SubjectName' 

If @TeachingGroup != 'Select All' 
    Set @sql += ' And TeachingGroup = @TeachingGroup' 

If @SubGroup != 'Select All' 
    Set @sql += ' And Gender = Right(@SubGroup, 1)' 

Exec sp_executesql @sql, @params, 
    @StuYear, @DataCollection, @SubjectName, @TeachingGroup, @SubGroup 
+0

이 답변은 저에게 효과적이었습니다. 나도 그것을 밖으로 시도하는 두 가지 옵션을 가지고, 그래서 내가 미래에 동적 SQL 메서드를 사용하여 고려 될거야 좋아하지만 지금은 표준 결과가 잘 작동합니다. – Matt

1

동적 SQL을 사용합니다.

DECLARE @StuYear INT, 
     @DataCollection VARCHAR(100), 
     @SubjectName NVARCHAR(50), 
     @TeachingGroup VARCHAR(100), 
     @Subgroup VARCHAR(3); 

SELECT @StuYear = 2013, 
     @DataCollection = 'Col1', 
     @SubjectName = N'Mark', 
     @TeachingGroup = 'Select All', 
     @Subgroup = 'GenM'; 

DECLARE @SqlStatement NVARCHAR(MAX), @Params NVARCHAR(MAX); 

SET @SqlStatement = N' 
SELECT ... 
FROM ... 
where 1=1 
AND  ([StuYear] = @StuYear) 
AND  ([DataCollection] = @DataCollection) 
AND  ([Name] = @SubjectName) ' + CHAR(13) 
+ CASE 
     WHEN @TeachingGroup <> 'Select All' THEN N'AND  ([TeachingGroup] = @TeachingGroup) ' + CHAR(13) 
     ELSE N'' 
    END 
+ CASE 
     WHEN @Subgroup = 'GenF' THEN N'AND  ([Gender] = ''F'') ' + CHAR(13) 
     WHEN @Subgroup = 'GenM' THEN N'AND  ([Gender] = ''M'') ' + CHAR(13) 
     ELSE N'' 
    END; 

-- PRINT @SqlStatement; 

SET @Params = N'@StuYear INT, @DataCollection VARCHAR(100), @SubjectName NVARCHAR(50)'; 

EXEC sp_executesql 
     @SqlStatement, 
     @Params, 
     @StuYear = @StuYear, 
     @DataCollection = @DataCollection, 
     @SubjectName = @SubjectName; 

참고 :이 증가 모든 조건이 AND를 사용하여 연결되어 있기 때문에 Index Seek을 얻기의 기회 (또한, 실행 계획은 OPTION (RECOMPILE) 달리 같은 @SqlStatement의 두 번째 실행을 시작 저장됩니다) 당신은해야 sp_executesql (SET = @Params = ... 참조) 내에서 매개 변수로 사용되는 변수를 비롯한 모든 변수에 대해 데이터 유형, 최대 길이 (필요한 경우 데이터 정렬)를 바꿉니다.

관련 문제