Advertising: Организация AlustemRu - всегда в наличии зимние сады для строительства. Монтажные работы. выбор эхолота ЗАО Glav-OknaRU , в каталоге - окна пвх цены для отделки. Online-консультации.
Интеллектуальный поиск средствами MS SQL Server (2000)
Многие сталкивались с необходимостью реализации интеллектального поиска по базе данных (думаю, что почти все). Тем, кто не нашел подходящего решения или тем, кто просто хотел бы взглянуть на альтернативные решения проблемы, будет полезен следующий код. Здесь я привожу свою реализацию хранимой процедуры поиска по БД. Возможно, она довольно узкая, т.к. я оптимизировал ее под конкретные задачи и логику. Требования к поисковому запросу таковы, что он может содержать любые символы: кирилицу, цифры, латиницу. спец. символы и т.п.. Итак, код в студию ...
CREATEPROCEDURESearch @Query AsVarchar(500) AS BEGIN /*Будем бить запрос на токены. В данном случае, разделяя по пробелу*/ Declare @SearchTokens Table ( [Token] Varchar(500) );
/*Временная табличка для результатов. Relevance - будет содержать вес результата*/ Declare @ResTable Table ( [ID] Int, [Name] Varchar(350), [Date] DateTime, [Relevance] SmallInt );
/*Удаляем начальные пробелы*/ Set @Query = LTrim(@Query);
/*Концевой символ должен быть пробел*/ IfSubstring(@Query, Len(@Query),1) <> ` ` Begin Set @Query = @Query + ` `; End;
/*Сводим все серии пробелов в строке до серий длиной в один символ*/ While Charindex(` `, @Query) <> 0 Begin Set @Query = Replace(@Query, ` `, ` `); End
/*Сколько будет токенов?*/ Set @Occurrences = Datalength(Replace(@Query, ` `, ` #`)) - Datalength(@Query); Set @tmpStr = @Query; Set @Cnt = 0 /*Бьем на токены и заполняем таблицы*/ While @Cnt <= @Occurrences Begin Set @Cnt = @Cnt + 1 /*Берем очередной токен*/ Set @CheckStr = Substring(@tmpStr, 1, Charindex(` `, @tmpStr) - 1); /*Ничего не делаем, если такой уже был*/ If (SELECT * FROM @SearchTokens WHERE [Token] = @CheckStr) Is Not Null Begin Continue; End /*добавляем к токенам*/ INSERTINTO @SearchTokens VALUES ( @CheckStr ); /*Небольшое "регулярное выражение". У меня - такое. Вы можете сюда поместить такое, какое необходимо*/ Set @CheckStr = `%` + @CheckStr + `%`; INSERTINTO @ResTable SELECT S.[ID], S.[Name], S.[Date] 0 FROM [SearchTable] S WHERE (S.[Name] LIKE @CheckStr OR YEAR ( S.[Date]) LIKE @CheckStr) ANDNOT (SELECT 1 FROM @ResTable WHERE [ID] = S.[ID]) ="#0000ff">FROM @SearchTokens WHERE [Token] = @CheckStr) Is Null; /*Отрезаем то, что проанализировали*/ Set @tmpStr = Substring(@tmpStr, Charindex(` `, @tmpStr) + 1, 500) If Datalength(@tmpStr) = 0 Begin Break; End; End;
/*Анализируем данные*/ Declare Curs CursorForSELECT * FROM @SearchTokens; Declare @Token AsVarchar(500); Open Curs; Fetch Curs Into @Token; While@@FETCH_STATUS = 0 Begin UPDATE @ResTable SET [Relevance] = [Relevance] + 1 WHERE [Name] LIKE`%` + @Token + `%`; UPDATE @ResTable SET [Relevance] = [Relevance] + 1 WHEREYEAR ( [Date]) LIKE`%` + @Token + `%`; Fetch Curs Into @Token; End; Close Curs; Deallocate Curs; /*Отдаем результаты упорядочивая по весу */ SELECT [ID] , [Name], [Date] FROM @ResTable ORDERBY [Relevance] DESC; END