2009-10-13 4 views
0

SQL Server 2008에 5 개의 nvarchar (최대) 열이있는 데이터베이스 테이블이 있습니다. 우리는 CONTAINS 함수를 사용하여이 열의 텍스트를 찾습니다.SQL Server 동적 열 목록에 함수 포함

우리는 이러한 종류의 쿼리를 사용하여 모든 다섯 개의 열에서 찾아보실 수 있습니다 :

SELECT * 
FROM SomeTable ST 
WHERE CONTAINS((ST.ColumnA, ST.ColumnB, ST.ColumnC, ST.ColumnD, ST.ColumnE) , '"Strawberry"') 

이제 우리는 동적으로 이러한 열 중 하나 이상에 대한 텍스트를 검색합니다. 예를 들어 ColumnB와 ColumnE 만 살펴보십시오. CASE 문을 사용하여 시도했지만 할 수 없습니다.

내가 생각할 수있는 유일한 해결책은 동적 SQL이지만이 문제를 피하는 것이 좋습니다. 전체 쿼리는 매우 복잡합니다. 동적 SQL을 사용하지 않고이 작업을 수행 할 수있는 방법이 있습니까?

답변

0

나는이 같은 솔루션에서 생각할 수 있지만 전체 텍스트 검색을 사용하지는 않습니다. 검색이 유용하다는 것을 알려주세요.

SELECT * 
FROM SomeTable ST 
WHERE 1=1 
AND ((@colA = '') OR ST.ColumnA LIKE @colA) 
AND ((@colB = '') OR ST.ColumnB LIKE @colB) 
AND ((@colC = '') OR ST.ColumnC LIKE @colC) 
AND ((@colD = '') OR ST.ColumnD LIKE @colD) 
AND ((@colE = '') OR ST.ColumnE LIKE @colE) 

search_on 매개 변수는 비트 (0, 1) 일 수 있으므로 1로 설정하면 해당 열의 검색이 활성화됩니다.

+0

:

당신은 같은 것을 끝낼 것이다. – HLGEM

+0

SQL이 논리를 바로 가기로 생각한다면 '대신'또는 '절을 사용 하시겠습니까?'또는 '그래서 첫 번째 절이 거짓이되어 지름길을 만들었습니까? – Andrew

+0

괄호 안의 OR은 첫 번째 매개 변수가 비어 있으면 두 번째 조건을 확인하지 않으며 각 "AND"줄에 대해서도 마찬가지라고 SQL에 알립니다 –

1

동적 SQL 사용을 피하는 유일한 방법은 임시 테이블과 if 문을 사용하고 proc을 저장하는 것입니다. 해당 열을 검색 할 텍스트가 포함 된 각 열에 대한 매개 변수가있는 저장된 proc가 있어야합니다. 중간 결과를 저장하기 위해 임시 테이블이나 테이블 변수를 만듭니다.

가능한 각 열에 대해 5 가지 if 문을 하나씩 사용합니다. 각 경우 변수가 널이 아닌 경우 임시 테이블에 삽입하십시오. 예 :

IF @ColA is not null 
BEGIN 
INSERT INTO #temp 
SELECT * FROM SomeTable ST 
     WHERE CONTAINS((ST.ColumnA) , @ColA) 
END 

마지막으로 결과를 표시하려면 임시 테이블을 선택하십시오.

매우 많은 열이 없으며 더 많은 열이 추가되지는 않을 것입니다. 솔직히, 동일한 검색 문자열에 대한 전체 텍스트 검색을 수행하는 데 필요한 여러 열이 있다는 사실은 나에게 데이터베이스 디자인에 대한 기본 문제가 있음을 나타냅니다.

0

5 개의 개별 사례를 결합한 다음 PIVOT을 결합하여 결합 할 수 있습니다. 동적 SQL보다 더 나은지 확실하지 않습니다. 하지 포함 전체 텍스트 검색을 사용하지 않는

SET @FindKey = '%B%E%' -- This is your search which field criteria 

WITH RESULTS1 AS (
    SELECT PK, 'A' AS Col 
    FROM SomeTable ST 
    WHERE @FindKey LIKE '%A%' AND CONTAINS(ST.ColumnA, '"Strawberry"') 
    UNION 
    SELECT PK, 'B' AS Col 
    FROM SomeTable ST 
    WHERE @FindKey LIKE '%B%' AND CONTAINS(ST.ColumnB, '"Strawberry"') 
    UNION 
    SELECT PK, 'C' AS Col 
    FROM SomeTable ST 
    WHERE @FindKey LIKE '%C%' AND CONTAINS(ST.ColumnC, '"Strawberry"') 
    UNION 
    SELECT PK, 'D' AS Col 
    FROM SomeTable ST 
    WHERE @FindKey LIKE '%D%' AND CONTAINS(ST.ColumnD, '"Strawberry"') 
    UNION 
    SELECT PK, 'E' AS Col 
    FROM SomeTable ST 
    WHERE @FindKey LIKE '%E%' AND CONTAINS(ST.ColumnE, '"Strawberry"') 
) 
,RESULTS2 AS (
SELECT PK, ISNULL([A], '') + ISNULL([B], '') + ISNULL([C], '') + ISNULL([D], '') + ISNULL([E], '') AS FoundKey 
FROM RESULTS PIVOT (MIN(Col) FOR Col IN ([A], [B], [C], [D], [E])) AS pvt 
) 
SELECT * 
FROM SomeTable 
INNER JOIN RESULTS2 
    ON RESULTS2.PK = SomeTable.PK 
WHERE RESULTS2.FoundKey LIKE @FindKey 
+0

필자는 피벗 테이블에 대해 생각하지 못했지만 이것이 부울 검색에 문제가 있다고 생각합니다. "딸기와 바나나"를 검색하면 단 하나의 열에 두 단어가 모두있는 단어 만 찾습니다. "strawberries"가 ColumnA에 있고 "bananas"가 ColumnB에 있으면 레코드를 반환하지 않습니다. 맞습니까? –

+0

네, 그 논리를 UNION으로 확장해야하는 것과 같은 일을하는 것은 맞습니다. 동적 SQl이 좋은 옵션이라고 생각합니다. –