2012-06-13 2 views
2

기본적으로 사용자는 SQL 데이터베이스에서 항목 목록을 작성해야하지만 사용자는 7 개의 필터를 조합하여 선택할 수 있으며 주문할 열을 선택할 수도 있습니다. 방향에 따른 순서.정렬, 정렬, 필터링 SQL 서버의 복잡한 혼합

이것은 상상할 수있는 것처럼 많은 조합으로 코드를 작성할 수 있으며 데이터 세트가 상당히 크기 때문에이 애플리케이션에서이 작업을 수행하지 않는 것이 좋습니다. 내 저장 프로 시저에서

지금까지 내가 시도 :

쿼리 문자열을 구축이 매우 간단하고 쉽게 따라하지만, 그것은 그래서 오히려이를 방지 할 SQL 주입에 열려있는 응용 프로그램을 떠난다.

IF ELSE 문을 사용하여 올바른 매개 변수화 된 SQL을 실행 해 보았지만이 작업이 거대한 트리가되어 유지 관리가 어려울 수 있습니다.

저는이 같은 해결책이 필요한 사람이 아니며 위의 방법보다 더 좋은 방법이 있어야합니까? 또한 부차적 질문으로 많은 IF를 수행하는 것 외에도 매개 변수화 된 방식으로 지시에 따라 주문하고 주문하는 좋은 방법이 있습니까? 이것은 아주 간단하고 추적에 쉽게 있지만 쿼리 문자열을 구축

+0

: 당신이 어떤 선택이 끝난 열을 기준으로 주문하는 CASE 문을 사용할 수 있습니다 this http://www.sommarskog.se/dyn-search-2008.html –

답변

1

필터링의 경우 COELSCE을 사용하여 임의의 조건 조합으로 필터링하십시오.매개 변수 중 하나가 null의 경우, 조건이 생략됩니다

SELECT * 
FROM YourTable t 
WHERE 1 = 1 
AND t.FirstColumn = COALESCE(@FirstColumnParam, t.FirstColumn) 
AND t.SecodndColumn = COALESCE(@SecondColumnParam, t.SecondColumn) 
.... 

: 저장 프로 시저에서 무언가 같이 될 것입니다 귀하의 질의에 다음, 사용자가 검색 할 수있는 모든 매개 변수의 목록이있을 것입니다. 1=1에 해당하는 경우에는 필터가 없습니다. 검색어가 쿼리에 전달됩니다. 주문에 대한

: 당신이 '와 (FLD1 = @ 필터 1 또는 @ 용 필터 1가 null)`당신이 읽어야 할 필터를 줄일 수 있다면

ORDER BY (CASE WHEN @OrderByParam = 1 Then FirstColumn ELSE .... END) 
+0

COALESCE 함수를 사용하는 경우 최적화 프로그램이 SARG이며 인덱스를 사용합니까? – buckley

+0

@buckley, 아니요, 여러분이'AND (FirstColumn = @FirstColumnParam OR @FirstColumnParam이 NULL 임)'라고 쓰여진 경우에 인덱스를 만들 것이라고 생각합니다. –

+0

@MahmoudGamal 대단히 감사합니다. 너무 많은 좋은 SQL 키워드가 있습니다. – radm4

1

, 그것은 그래서 나는 오히려이를 방지 할 SQL 주입에 열려있는 응용 프로그램을 떠난다.

당신은 sp_executesql을를 사용하고 sproc에 어린 아이 인수로 매개 변수를 전달하지 않을 경우. 매개 변수로 당신은 당신의 데이터를 제공하기 때문에

http://sqlinthewild.co.za/index.php/2009/04/03/dynamic-sql-and-sql-injection/

http://blogs.msdn.com/b/raulga/archive/2007/01/04/dynamic-sql-sql-injection.aspx

가 나는 또한 ELSE 문이 빠르게 그러나이 적절한 매개 변수화 SQL을 실행하는 경우의 집합을 사용하려고했습니다에는 SQL 인젝션에게이 없을 것 거대한 나무가되고 유지하는 악몽이 일 것입니다. 당신이 다른 경우 사용하는 경우

동의하지만 캐치라는 패턴도 있습니다 모든 쿼리

WHERE (ProductID = @Product Or @Product IS NULL) 
AND (ReferenceOrderID = @OrderID OR @OrderID Is NULL) 
... 
여기 http://sqlinthewild.co.za/index.php/2009/03/19/catch-all-queries/

더 많은 정보 끝에 OPTION (RECOMPILE)를 지정해야합니다 그렇지 않으면 쿼리가 매개 변수 스니핑으로 불려질 ​​수 있습니다.

당신은 sp_executesql을 때와 수 또는 모든 쿼리를 잡을 결국 Dynamic Sorting within SQL Stored Procedures

의 582,143,210

가능한 복제 (이 다음이 솔루션을 시도하여 일반적인 문제입니다). 나는 항상 모든 쿼리를 잡아 먹지 만 옵션을 지정하는 것을 잊지 마라 (재 컴파일).

+0

'where' 절을'sp_executesql'의 인수로 넘길 수 없습니다. 그리고 만약 당신이 sp_executesql을 동적으로 SQL 인자로 만들면, 그것은 물론 SQL injection을 위해 열리게됩니다. – Andomar

+0

@Andomar 나는 sproc에 인자로 넘겨 주어야한다는 대답을 명확히했습니다. 난 그냥 캐치 올 모든 옵션을 다시 컴파 일할 것, 또한 동적 순서를 단순화 할 것입니다 – buckley