在SQL Server 2008中创建将执行“Facebook搜索”的存储过程

时间:2010-06-07 23:30:57

标签: sql-server-2008 stored-procedures full-text-search

我正在尝试在我的系统中实现Facebook搜索(在键入时自动建议)。 我已经成功编写了所有ajax代码,但我不确定如何查询数据库。

我创建了一个名为People的表,其中包含以下字段:ID,FirstName,LastName,MiddleName,Email。 我还在所有这些领域创建了一个FTS索引。

我想创建一个存储过程,它将查询框中插入的文本作为参数,并返回建议。

例如,当我在文本框中写入查询“Joh Do”时 它将转换为查询:

select * from People where contains(*, '"Joh*"') and contains(*, '"Do*"')

有没有办法在存储过程中执行此操作?

P.S 我试过使用语法

select * from People where contains(*,'"Joh*" and "Do*"')

但它没有返回预期的结果,可能是因为它需要搜索不同字段的单词。有办法解决这个问题吗?

感谢。

3 个答案:

答案 0 :(得分:1)

尝试

select   *
from     People
where    (FirstName  Like '%'+ @FirstName  + '%') and
         (MiddleName Like '%'+ @MiddleName + '%') and
         (LastName   Like '%'+ @LastName   + '%')

此外,您可能希望将结果限制为仅使用以下内容返回最大值10:

select top 10

编辑1:

好的,我现在更好地理解这个问题了。我会使用动态sql:

首先创建一个分割函数,例如Example Split function using XML trick

然后使用动态sql:

declare @tstr varchar (500)

set @tstr = ''

select  @tstr =@tstr + ' Contains(*, ''"'+ val + '*")' + ' and '
from  dbo.split(@SearchStr, ' ') 


set @tstr =  left(@tstr,len(@tstr)-4)

select @tstr
Declare @dsql as varchar(500)

set @dsql = 'select * from People where '+ @tstr

exec (@dsql)

另请注意,根据Remus,请注意SQL注入,使用 sp_executesql (而不是EXEC)会更好。

答案 1 :(得分:1)

问题是参数的开放列表性质。我可以是Joh,可以是Joh Do,也可以是Joh Do Na,依此类推。您有两个主要的选择:

  • 解析Web应用程序中的输入(在我假设的ASP中),然后调用适当的过程以获得条目数(即exec usp_findSuggestions1 'Joh'exec usp_findSuggestions2 'Joh', 'Do'exec usp_findSuggestions1 'Joh', 'Do', 'Na')。第一个过程使用1 contains,第二个过程有2个contains .. and contains ...,最后一个过程有3个。这可能看起来很糟糕,从DRY,代码设计和特殊代码维护pov,但实际上是最好的解决方案,因为就T-SQL而言,主要是由于这些查询的计划稳定性。
  • 将输入直接传递到单个存储过程,您可以在其中将其拆分为组件,并根据需要构建具有contains的动态T-SQL查询。

两种解决方案都不完美。最终,你有两个问题,两个问题都已经过深入调查:

答案 2 :(得分:0)

AJAX工具包具有“自动完成”控件,可提供开箱即用的此功能。它使用起来非常简单。

查看示例here