且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在SQL Server 2005中用存储过程实现搜索功能

更新时间:2022-09-08 10:59:52

现在很多网站都提供了站内的搜索功能,有的很简单在SQL语句里加一个条件如:where names like ‘%words%’就可以实现最基本的搜索了。

我们来看看功能强大一点,复杂一点的搜索是如何实现的(在SQL SERVER200/2005通过存储过程实现搜索算法)。

我们把用户的搜索可以分为以下两种:

1.精确搜索,就是把用户输入的各个词语当成一个整体,不分割搜索.

2.像百度,GOOGLE一样的,按空格把输入的每一个词分离,只要包含这些词语,而不管出现的顺序,称为ALL-Word Search.

3.对输入的词只要有一个出现就为匹配 称为Any-Word Search


一、对搜索结果进行排序的算法

在前面提到的LIKE语句最大的问题就是搜索的结果是没有经过排序的,我们不知道结果出现在的顺序是如何的,因为它是随机的。像百度,GOOGLE都会对结果用算法进行排序再显示的.好我们也来建立一个简单的排序法。一个很常见的算法是计算关键词在被搜索内容中出现的次数,次数最多的排在结果的第一位。我们的是在存储过程中实现这个算法的,而在SQLSERVER中没有提供计算关键词在被搜索内容中出现的次数这样的函数,我们要自己写一个UDFUser-Defined Functions,UDFSQLSERVER的内部函数,可以被存储过程调用或者被其他UDF调用。函数如下:

1在SQL Server 2005中用存储过程实现搜索功能CREATE FUNCTION dbo.WordCount
2在SQL Server 2005中用存储过程实现搜索功能
3在SQL Server 2005中用存储过程实现搜索功能(@Word VARCHAR(15),
4在SQL Server 2005中用存储过程实现搜索功能
5在SQL Server 2005中用存储过程实现搜索功能@Phrase VARCHAR(1000))
6在SQL Server 2005中用存储过程实现搜索功能
7在SQL Server 2005中用存储过程实现搜索功能RETURNS SMALLINT
8在SQL Server 2005中用存储过程实现搜索功能
9在SQL Server 2005中用存储过程实现搜索功能AS
10在SQL Server 2005中用存储过程实现搜索功能
11在SQL Server 2005中用存储过程实现搜索功能BEGIN
12在SQL Server 2005中用存储过程实现搜索功能
13在SQL Server 2005中用存储过程实现搜索功能在SQL Server 2005中用存储过程实现搜索功能/**//* 如果@Word 或者@Phrase 为空返回 0 */
14在SQL Server 2005中用存储过程实现搜索功能
15在SQL Server 2005中用存储过程实现搜索功能IF @Word IS NULL OR @Phrase IS NULL RETURN 0
16在SQL Server 2005中用存储过程实现搜索功能
17在SQL Server 2005中用存储过程实现搜索功能在SQL Server 2005中用存储过程实现搜索功能/**//* @BiggerWord 比@Word长一个字符 */
18在SQL Server 2005中用存储过程实现搜索功能
19在SQL Server 2005中用存储过程实现搜索功能DECLARE @BiggerWord VARCHAR(21)
20在SQL Server 2005中用存储过程实现搜索功能
21在SQL Server 2005中用存储过程实现搜索功能SELECT @BiggerWord = @Word + 'x'
22在SQL Server 2005中用存储过程实现搜索功能
23在SQL Server 2005中用存储过程实现搜索功能在SQL Server 2005中用存储过程实现搜索功能/**//*在 @Phrase用@BiggerWord替换@Word */
24在SQL Server 2005中用存储过程实现搜索功能
25在SQL Server 2005中用存储过程实现搜索功能DECLARE @BiggerPhrase VARCHAR(2000)
26在SQL Server 2005中用存储过程实现搜索功能
27在SQL Server 2005中用存储过程实现搜索功能SELECT @BiggerPhrase = REPLACE (@Phrase, @Word, @BiggerWord)
28在SQL Server 2005中用存储过程实现搜索功能
29在SQL Server 2005中用存储过程实现搜索功能在SQL Server 2005中用存储过程实现搜索功能/**//* 相减结果就是出现的次数了 */
30在SQL Server 2005中用存储过程实现搜索功能
31在SQL Server 2005中用存储过程实现搜索功能RETURN LEN(@BiggerPhrase) - LEN(@Phrase)
32在SQL Server 2005中用存储过程实现搜索功能
33在SQL Server 2005中用存储过程实现搜索功能END
34在SQL Server 2005中用存储过程实现搜索功能

以上就是整个UDF,它用了一个很高效的方法来计算关键词出现的次数。

二、参数传递

用户输入的关键词从一个到多个不等,我们可以把参数固定为@word1~@word5,这样比较方面实现。当用户输入超过5个时,忽略不计,少于5个的地方视为空。其实GOOGLE也是这样做的,只是GOOGLE的最大词语限制是10个。

三、搜索的实现过程

假定我们对Product表进行搜索,Product字段有:Id,Name ,Descripton(产品描述),搜索要同时对Name Description进行。

Any-World Search实现如下:

1在SQL Server 2005中用存储过程实现搜索功能SELECT Product.Name,
2在SQL Server 2005中用存储过程实现搜索功能3 * WordCount(@Word1, Name) + WordCount(@Word1, Description) +
3在SQL Server 2005中用存储过程实现搜索功能
4在SQL Server 2005中用存储过程实现搜索功能3 * WordCount(@Word2, Name) + WordCount(@Word2, Description) +
5在SQL Server 2005中用存储过程实现搜索功能
6在SQL Server 2005中用存储过程实现搜索功能在SQL Server 2005中用存储过程实现搜索功能
7在SQL Server 2005中用存储过程实现搜索功能
8在SQL Server 2005中用存储过程实现搜索功能AS Rank
9在SQL Server 2005中用存储过程实现搜索功能FROM Product
10在SQL Server 2005中用存储过程实现搜索功能
11在SQL Server 2005中用存储过程实现搜索功能

这里对Name赋予权重为3Description1(大家根据实际情况赋予不同的权重),Rank是计算列,通过前面定义的UDF计算所关键词出现的次数乘上权重等到的。


同样的
All-Word Search实现如下:

1在SQL Server 2005中用存储过程实现搜索功能SELECT Product.Name,
2在SQL Server 2005中用存储过程实现搜索功能
3在SQL Server 2005中用存储过程实现搜索功能 (3 * WordCount(@Word1, Name) + WordCount(@Word1, Description)) *
4在SQL Server 2005中用存储过程实现搜索功能
5在SQL Server 2005中用存储过程实现搜索功能CASE
6在SQL Server 2005中用存储过程实现搜索功能
7在SQL Server 2005中用存储过程实现搜索功能WHEN @Word2 IS NULL THEN 1
8在SQL Server 2005中用存储过程实现搜索功能
9在SQL Server 2005中用存储过程实现搜索功能ELSE 3 * WordCount(@Word2, Name) + WordCount(@Word2, Description)
10在SQL Server 2005中用存储过程实现搜索功能
11在SQL Server 2005中用存储过程实现搜索功能END *
12在SQL Server 2005中用存储过程实现搜索功能
13在SQL Server 2005中用存储过程实现搜索功能在SQL Server 2005中用存储过程实现搜索功能
14在SQL Server 2005中用存储过程实现搜索功能
15在SQL Server 2005中用存储过程实现搜索功能AS Rank
16在SQL Server 2005中用存储过程实现搜索功能
17在SQL Server 2005中用存储过程实现搜索功能FROM Product
18在SQL Server 2005中用存储过程实现搜索功能


这时把每个关键词出现的次数相乘只要一个没出现

RANK就为0,为0就是搜索结果为空。

还可以这样实现:


1在SQL Server 2005中用存储过程实现搜索功能SELECT Product.Name,
2在SQL Server 2005中用存储过程实现搜索功能CASE
3在SQL Server 2005中用存储过程实现搜索功能WHEN @Word1 IS NULL THEN 0
4在SQL Server 2005中用存储过程实现搜索功能ELSE ISNULL(NULLIF(dbo.WordCount(@Word1, Name + ' ' + Description), 0), -1000)
5在SQL Server 2005中用存储过程实现搜索功能END +
6在SQL Server 2005中用存储过程实现搜索功能CASE
7在SQL Server 2005中用存储过程实现搜索功能WHEN @Word2 IS NULL THEN 0
8在SQL Server 2005中用存储过程实现搜索功能ELSE ISNULL(NULLIF(dbo.WordCount(@Word2, Name + ' ' + Description), 0), -1000)
9在SQL Server 2005中用存储过程实现搜索功能END +
10在SQL Server 2005中用存储过程实现搜索功能在SQL Server 2005中用存储过程实现搜索功能
11在SQL Server 2005中用存储过程实现搜索功能AS Rank
12在SQL Server 2005中用存储过程实现搜索功能FROM Product

对没出现的关键词赋值-1000,这样Rank就肯定为负数,负数表示搜索结果为空。

四、对结果进行分页

搜索的结果可能很多,对结果分页可以提高性能。我在如何在数据层分页以提高性能已经说明了如何用存储过程进行分页了,这里就不在详细复述了。

过程简单来说就是创建一个临时表,表中包含行号,读取时按行号来读取数据


五、完整代码

经过前面的分析,完整代码如下:

1在SQL Server 2005中用存储过程实现搜索功能CREATE PROCEDURE SearchCatalog
2在SQL Server 2005中用存储过程实现搜索功能(
3在SQL Server 2005中用存储过程实现搜索功能@PageNumber TINYINT,
4在SQL Server 2005中用存储过程实现搜索功能@ProductsPerPage TINYINT,
5在SQL Server 2005中用存储过程实现搜索功能@HowManyResults SMALLINT OUTPUT,
6在SQL Server 2005中用存储过程实现搜索功能@AllWords BIT,
7在SQL Server 2005中用存储过程实现搜索功能@Word1 VARCHAR(15) = NULL,
8在SQL Server 2005中用存储过程实现搜索功能@Word2 VARCHAR(15) = NULL,
9在SQL Server 2005中用存储过程实现搜索功能@Word3 VARCHAR(15) = NULL,
10在SQL Server 2005中用存储过程实现搜索功能@Word4 VARCHAR(15) = NULL,
11在SQL Server 2005中用存储过程实现搜索功能@Word5 VARCHAR(15) = NULL)
12在SQL Server 2005中用存储过程实现搜索功能AS
13在SQL Server 2005中用存储过程实现搜索功能在SQL Server 2005中用存储过程实现搜索功能/**//* 创建临时表,保存搜索的结果(Sql Server2005适用,Sql Server2000见如何在数据层分页以提高性能) */
14在SQL Server 2005中用存储过程实现搜索功能DECLARE @Products TABLE
15在SQL Server 2005中用存储过程实现搜索功能(RowNumber SMALLINT IDENTITY (1,1) NOT NULL,
16在SQL Server 2005中用存储过程实现搜索功能 ID INT,
17在SQL Server 2005中用存储过程实现搜索功能 Name VARCHAR(50),
18在SQL Server 2005中用存储过程实现搜索功能 Description VARCHAR(1000),
19在SQL Server 2005中用存储过程实现搜索功能Rank INT)
20在SQL Server 2005中用存储过程实现搜索功能
21在SQL Server 2005中用存储过程实现搜索功能在SQL Server 2005中用存储过程实现搜索功能/**//* Any-words search */
22在SQL Server 2005中用存储过程实现搜索功能IF @AllWords = 0
23在SQL Server 2005中用存储过程实现搜索功能INSERT INTO @Products
24在SQL Server 2005中用存储过程实现搜索功能SELECT ID, Name, Description,
25在SQL Server 2005中用存储过程实现搜索功能3 * dbo.WordCount(@Word1, Name) + dbo.WordCount(@Word1, Description) +
26在SQL Server 2005中用存储过程实现搜索功能
27在SQL Server 2005中用存储过程实现搜索功能3 * dbo.WordCount(@Word2, Name) + dbo.WordCount(@Word2, Description) +
28在SQL Server 2005中用存储过程实现搜索功能
29在SQL Server 2005中用存储过程实现搜索功能3 * dbo.WordCount(@Word3, Name) + dbo.WordCount(@Word3, Description) +
30在SQL Server 2005中用存储过程实现搜索功能
31在SQL Server 2005中用存储过程实现搜索功能3 * dbo.WordCount(@Word4, Name) + dbo.WordCount(@Word4, Description) +
32在SQL Server 2005中用存储过程实现搜索功能
33在SQL Server 2005中用存储过程实现搜索功能3 * dbo.WordCount(@Word5, Name) + dbo.WordCount(@Word5, Description)
34在SQL Server 2005中用存储过程实现搜索功能
35在SQL Server 2005中用存储过程实现搜索功能AS Rank
36在SQL Server 2005中用存储过程实现搜索功能
37在SQL Server 2005中用存储过程实现搜索功能FROM Product
38在SQL Server 2005中用存储过程实现搜索功能ORDER BY Rank DESC
39在SQL Server 2005中用存储过程实现搜索功能
40在SQL Server 2005中用存储过程实现搜索功能在SQL Server 2005中用存储过程实现搜索功能/**//* all-words search */
41在SQL Server 2005中用存储过程实现搜索功能
42在SQL Server 2005中用存储过程实现搜索功能IF @AllWords = 1
43在SQL Server 2005中用存储过程实现搜索功能
44在SQL Server 2005中用存储过程实现搜索功能INSERT INTO @Products
45在SQL Server 2005中用存储过程实现搜索功能
46在SQL Server 2005中用存储过程实现搜索功能SELECT ID, Name, Description,
47在SQL Server 2005中用存储过程实现搜索功能
48在SQL Server 2005中用存储过程实现搜索功能 (3 * dbo.WordCount(@Word1, Name) + dbo.WordCount
49在SQL Server 2005中用存储过程实现搜索功能
50在SQL Server 2005中用存储过程实现搜索功能(@Word1, Description)) *
51在SQL Server 2005中用存储过程实现搜索功能
52在SQL Server 2005中用存储过程实现搜索功能CASE
53在SQL Server 2005中用存储过程实现搜索功能
54在SQL Server 2005中用存储过程实现搜索功能WHEN @Word2 IS NULL THEN 1
55在SQL Server 2005中用存储过程实现搜索功能
56在SQL Server 2005中用存储过程实现搜索功能ELSE 3 * dbo.WordCount(@Word2, Name) + dbo.WordCount(@Word2,
57在SQL Server 2005中用存储过程实现搜索功能
58在SQL Server 2005中用存储过程实现搜索功能Description)
59在SQL Server 2005中用存储过程实现搜索功能
60在SQL Server 2005中用存储过程实现搜索功能END *
61在SQL Server 2005中用存储过程实现搜索功能
62在SQL Server 2005中用存储过程实现搜索功能CASE
63在SQL Server 2005中用存储过程实现搜索功能
64在SQL Server 2005中用存储过程实现搜索功能WHEN @Word3 IS NULL THEN 1
65在SQL Server 2005中用存储过程实现搜索功能
66在SQL Server 2005中用存储过程实现搜索功能ELSE 3 * dbo.WordCount(@Word3, Name) + dbo.WordCount(@Word3,
67在SQL Server 2005中用存储过程实现搜索功能
68在SQL Server 2005中用存储过程实现搜索功能Description)
69在SQL Server 2005中用存储过程实现搜索功能
70在SQL Server 2005中用存储过程实现搜索功能END *
71在SQL Server 2005中用存储过程实现搜索功能
72在SQL Server 2005中用存储过程实现搜索功能CASE
73在SQL Server 2005中用存储过程实现搜索功能
74在SQL Server 2005中用存储过程实现搜索功能WHEN @Word4 IS NULL THEN 1
75在SQL Server 2005中用存储过程实现搜索功能
76在SQL Server 2005中用存储过程实现搜索功能ELSE 3 * dbo.WordCount(@Word4, Name) + dbo.WordCount(@Word4,
77在SQL Server 2005中用存储过程实现搜索功能
78在SQL Server 2005中用存储过程实现搜索功能Description)
79在SQL Server 2005中用存储过程实现搜索功能
80在SQL Server 2005中用存储过程实现搜索功能END *
81在SQL Server 2005中用存储过程实现搜索功能
82在SQL Server 2005中用存储过程实现搜索功能CASE
83在SQL Server 2005中用存储过程实现搜索功能
84在SQL Server 2005中用存储过程实现搜索功能WHEN @Word5 IS NULL THEN 1
85在SQL Server 2005中用存储过程实现搜索功能
86在SQL Server 2005中用存储过程实现搜索功能ELSE 3 * dbo.WordCount(@Word5, Name) + dbo.WordCount(@Word5,
87在SQL Server 2005中用存储过程实现搜索功能
88在SQL Server 2005中用存储过程实现搜索功能Description)
89在SQL Server 2005中用存储过程实现搜索功能
90在SQL Server 2005中用存储过程实现搜索功能END
91在SQL Server 2005中用存储过程实现搜索功能
92在SQL Server 2005中用存储过程实现搜索功能AS Rank
93在SQL Server 2005中用存储过程实现搜索功能
94在SQL Server 2005中用存储过程实现搜索功能FROM Product
95在SQL Server 2005中用存储过程实现搜索功能
96在SQL Server 2005中用存储过程实现搜索功能ORDER BY Rank DESC
97在SQL Server 2005中用存储过程实现搜索功能
98在SQL Server 2005中用存储过程实现搜索功能在SQL Server 2005中用存储过程实现搜索功能/**//* 在外部变量保存搜索结果数 */
99在SQL Server 2005中用存储过程实现搜索功能
100在SQL Server 2005中用存储过程实现搜索功能SELECT @HowManyResults = COUNT(*)
101在SQL Server 2005中用存储过程实现搜索功能
102在SQL Server 2005中用存储过程实现搜索功能FROM @Products
103在SQL Server 2005中用存储过程实现搜索功能
104在SQL Server 2005中用存储过程实现搜索功能WHERE Rank > 0
105在SQL Server 2005中用存储过程实现搜索功能
106在SQL Server 2005中用存储过程实现搜索功能在SQL Server 2005中用存储过程实现搜索功能/**//* 按页返回结果*/
107在SQL Server 2005中用存储过程实现搜索功能
108在SQL Server 2005中用存储过程实现搜索功能SELECT ProductID, Name, Description, Price, Image1FileName,
109在SQL Server 2005中用存储过程实现搜索功能
110在SQL Server 2005中用存储过程实现搜索功能 Image2FileName, Rank
111在SQL Server 2005中用存储过程实现搜索功能
112在SQL Server 2005中用存储过程实现搜索功能FROM @Products
113在SQL Server 2005中用存储过程实现搜索功能
114在SQL Server 2005中用存储过程实现搜索功能WHERE Rank > 0
115在SQL Server 2005中用存储过程实现搜索功能
116在SQL Server 2005中用存储过程实现搜索功能AND RowNumber BETWEEN (@PageNumber-1) * @ProductsPerPage + 1
117在SQL Server 2005中用存储过程实现搜索功能
118在SQL Server 2005中用存储过程实现搜索功能AND @PageNumber * @ProductsPerPage
119在SQL Server 2005中用存储过程实现搜索功能ORDER BY Rank DESC



本文转自高海东博客园博客,原文链接:http://www.cnblogs.com/ghd258/archive/2006/11/17/563218.html,如需转载请自行联系原作者