Динамический список столбцов SQL Server содержит функцию - PullRequest
0 голосов
/ 14 октября 2009

У меня есть таблица базы данных в SQL Server 2008 с 5 столбцами nvarchar (max). Мы используем функцию CONTAINS для поиска текста в этих столбцах.

Мы можем просмотреть все пять столбцов, используя такой запрос:

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

Теперь мы хотим динамически искать текст для одного или нескольких из этих столбцов. Например, смотрите только в ColumnB и ColumnE. Я пытался использовать оператор CASE, но не смог.

Единственное решение, которое я могу придумать, - это динамический SQL, но я бы предпочел этого избежать. (Полный запрос очень сложен.) Есть ли способ сделать это без использования динамического SQL?

Ответы [ 3 ]

1 голос
/ 14 октября 2009

Единственный способ избежать использования динамического SQL - использовать временную таблицу, а также операторы if и хранимые процедуры.Иметь сохраненный процесс с параметрами для каждого из столбцов, которые включают текст для поиска в этих столбцах.Создайте временную таблицу или табличную переменную для хранения промежуточных результатов.

Пять различных операторов if для каждого возможного столбца.В каждом if вставить в временную таблицу, если переменная не равна нулю.что-то вроде:

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

В конце выберите из временной таблицы, чтобы показать свой результат.

Это работает только хорошо, хотя, если у вас не очень много столбцов, и вряд ли будет добавлено больше.Честно говоря, тот факт, что у вас есть несколько столбцов, вам необходимо выполнить полнотекстовый поиск для одной и той же строки поиска, указывает на то, что у вас могут быть основные проблемы с дизайном базы данных.

0 голосов
/ 14 октября 2009

Вы можете объединить 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 голосов
/ 14 октября 2009

Я просто могу подумать над решением, подобным этому, но оно не использует полнотекстовый поиск ... дайте мне знать, если оно вам пригодится.

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 поиск по этому столбцу будет активирован.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...