2010-11-18 47 views
4

试图做一个小的存储过程中的所有单词,而无需添加自由文本索引只为这(SQL Server 2008中)搜索包含从另一个字符串

基本上是一个varchar字段,我想找到的所有记录,其中有一定字段包含来自参数的所有单词。因此,如果在字段中我有“这是一个测试字段”,并且我的SP的参数将是“this test field”,它将返回它,就像参数是“field this test”一样。

该表非常小(4000)记录和负载会很低,所以效率不是什么大不了的。现在我能想到的唯一解决方案是将两个字符串与表值函数分开并从那里开始。

任何更简单的想法?

谢谢!

回答

1

这是一个使用递归CTE的解决方案。这实际上使用了两个单独的递归。第一个将字符串拆分为令牌,第二个使用每个令牌递归地过滤记录。

declare  
    @searchString varchar(max), 
    @delimiter char; 

select 
@searchString = 'This is a test field' 
,@delimiter = ' ' 

declare @tokens table(pos int, string varchar(max)) 

;WITH Tokens(pos, start, stop) AS (
     SELECT 1, 1, CONVERT(int, CHARINDEX(@delimiter, @searchString)) 
     UNION ALL 
     SELECT pos + 1, stop + 1, CONVERT(int, CHARINDEX(@delimiter, @searchString, stop + 1)) 
     FROM Tokens 
     WHERE stop > 0 
    ) 
    INSERT INTO @tokens 
    SELECT pos, 
     SUBSTRING(@searchString, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) AS string 
    FROM Tokens 
    OPTION (MAXRECURSION 25000) ; 

;with filter(ind, myfield) as (
    select 1,myfield from mytable where myfield like '%'+(select string from @tokens where pos = 1)+'%'  
    union all 
    select ind + 1, myfield from filter where myfield like '%'+(select string from @tokens where pos = ind + 1)+'%'  
    ) 

    select * from filter where ind = (select COUNT(1) from @tokens) 

这我花了大约15秒,搜索的10K记录的表搜索字符串“这是一个测试场”。(字符串中的更多的话,它需要较长的..)

编辑
如果你想有一个模糊搜索,即返回密切匹配的结果,即使有wasnt完全匹配,你可以修改的最后一行的查询是 -
select * from (select max(ind) as ind, myfield from filter group by myfield) t order by ind desc

“IND”禾uld给你从myfield中找到的搜索字符串中的单词数量。

2

如果效率不是一个大问题,为什么不用一点动态SQL。例如:

create procedure myproc (@var varchar(100)) 
as 
set @var = '%' + replace(@var, ' ', '%') + '%' 
exec ('select * from mytable where myfield like '''+ @var + '''') 
+0

这只会返回具有与参数 – 2010-11-18 14:55:56

+0

好主意(+1)相同顺序的搜索词的那些行,只要确保所有单词之间有足够空间。 – 2010-11-18 14:57:47

相关问题