2009-07-08 1 views
1

Я пишу довольно сложную хранимую процедуру для поиска библиотеки изображений.MS-SQL 2005 поиск: условное, где предложение с freetext

Я собирался использовать представление и написать динамического SQL для запроса мнение, но мне нужно использовать полнотекстовый индекс, и мой взгляд нужно внешнее соединение (MS-SQL 2005 full-text index on a view with outer joins)

Итак, я вернулся к хранимую процедуру.

мне нужно искать на (все по желанию):

  • общий поисковый запрос, который использует полнотекстовый индекс (или без условий поиска)
  • одну или несколько категорий (или без него)
  • (или нет)

Есть ли способ сделать условный FREETEXT в предложении «ГДЕ»? Запрос может быть пустым, и в этом случае я хочу проигнорировать это или просто вернуть все соответствия FTI.

... AND FREETEXT(dbo.MediaLibraryCultures.*, '"* "'), похоже, не работает. Не знаете, как здесь будет работать инструкция.

Мне лучше вставить результаты фильтра категории/тега в переменную temp table/table, а затем присоединиться к результатам поиска FTI? Таким образом, я могу выполнить соединение только в том случае, если задан поисковый запрос.

Мысли?

+0

Обращайте внимание на ваш выбор тегов. 'sql-server' outnumbers 'mssql' 6000: 1 –

+0

Спасибо. Было бы неплохо объединить и удалить те повторяющиеся теги ... – ScottE

ответ

0

Хм, я думал, что не было короткого замыкания на сервере sql?

AND (@q = '' OR FREETEXT(dbo.MediaLibraryCultures.*, @q)) 

, похоже, работает просто отлично!

Странно, полное сканирование текста по-прежнему является частью плана выполнения.

+0

Интересно, что полный текстовый поиск находится в плане выполнения - я думал, что оптимизатор запросов увидит @q и '' как константы, и исключит всю проверку (делая любое короткое замыкание несущественным, поскольку оно даже не будет включено в конечный запрос), но я думаю, так как запрос может влиять на переменную для каждой строки, оптимизатор не может этого принять. Мне также интересно узнать, занимает ли полнотекстовый поиск в плане выполнения много времени? Также, если это ответ, с которым вы работаете, ум, обозначающий его как принятый ответ? – Tetraneutron

+0

Я также проверил небольшой тест, чтобы проверить, не вызывает ли SQL короткое замыкание, результаты немного запутываются create table #tempShort (a int) select * from #tempShort где (1/0)> 1 выберите * from # tempShort где 1 = 1 или (1/0)> 1 выберите * from #tempShort где (1/0)> 1 или 1 = 1 drop table #tempShort Если бы это было короткое замыкание, я ожидал бы первого и третьего выбирает сбой с последующим вторым, но как второй, так и третий успех, сделайте, какие выводы вы сделаете. – Tetraneutron

+0

Да, я собираюсь с этим ответом. Я не могу отметить его как принятый - придется ждать 48 часов. План выполнения показал одинаковое количество времени для шага fti независимо от того, был ли @q пустым или нет. Однако это не очень хороший тест в моем случае, поскольку FTI в настоящее время довольно мала. – ScottE

0

Вы можете добавить проверку на пустую строку поиска как

where ... 
AND (FREETEXT(dbo.MediaLibraryCultures.*, @FreeTextSearchFor) OR @FreeTextSearchFor = '') 

(У меня есть ощущение, что FREETEXT поиск не может быть нулевым, передаваемые в них, так что я по сравнению с пустой строкой)

Если термин для поиска пуст, предложение whole будет оцениваться как true, поэтому никакие ограничения не будут применяться (по этому предложению) к возвращенным строкам и, конечно, поскольку его константа сравнивается с переменной - I подумал бы, что оптимизатор вступит в игру и не выполнит это сравнение для каждой строки.

+0

Нет, предикат не может быть пустым или пустым. – ScottE

1

Я знаю, что через год и более новая версия SQL, но FYI ...

Я использую SQL Server 2008 и попытались короткого замыкания с помощью

AND (@searchText = '' OR freetext(Name, @searchText)) 

и я получаю сообщение «Null или пустой полнотекстовый предикат» при установке @searchText = ''. Думаю, что-то в 2008 году изменилось, что в этом случае не работает.

+0

Интересно. К счастью, мы все еще работаем в 2005 году. – ScottE

0

Не работает на SQL Server 2014. Я попробовал предложенное короткое замыкание в одной из моих хранимых процедур, но он продолжает оценивать выражение FREETEXT.Единственным решением, которое я нашел, является следующее:

IF ISNULL(@Text, N'') = N'' SET @Text = N'""' 

SELECT ... 
    WHERE ... 
    AND (@Text = '""' OR FREETEXT([Data], @Text) 
Смежные вопросы