站内通用搜索之存储过程(完美版)
一个好的网站,搜索的性能是个很重要的标准,通常简单的方法就是使用SQL提供的‘LIKE’关键字,虽然能基本满足需要,但不能永远停留在这种水平下,为此,特向大家推荐一个功能比较强,性能有很好的方法。
方法概括:能同时搜索5个关键字(根据需要确定),搜索的对象项有个权值,在这里我用了两个项,3:1的,好拉,还是来看步骤吧!
分两步走:
第一步:创建一个自定义函数(2005 里面叫‘标量函数’)WordCount
CREATE FUNCTION [dbo].[WordCount]
(
@word varchar(15),
@phrase varchar(600)
)
RETURNS SMALLINT
AS
BEGIN
/* 如果@Word或@Phrase为空返回0*/
IF @Word is null or @Phrase is null RETURN 0
/*@BiggerWord比@Word长一个字符*/
DECLARE @BiggerWord varchar(21)
SELECT @BiggerWord=@Word+'x'
/*在@phrase 用 @BiggerWord替换@Word*/
DECLARE @BiggerPhrase varchar(1000)
SELECT @Biggerphrase= REPLACE (@Phrase,@word,@BiggerWord)
/*相减结果就是出现的次数了*/
RETURN LEN(@BiggerPhrase)-LEN(@PHRASE)
END
说明:这个函数主要是统计关键字在相应的对象里面出现的次数。
下面是全码:
ALTER PROCEDURE [dbo].[compsearch]
-- Add the parameters for the stored procedure here
@areacode varchar(20)='%',
@PageNumber TINYINT,
@PerPage TINYINT,
@AllWords BIT,
@HowManyResults SMALLINT OUTPUT,
@word1 varchar(25)=null,
@word2 varchar(25)=null,
@word3 varchar(25)=null,
@word4 varchar(25)=null,
@word5 varchar(25)=null
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @Temcompany TABLE
(
RowNumber SMALLINT IDENTITY (1,1) NOT NULL ,
areacode nvarchar(28),
u_name nvarchar(20),
corpname nvarchar(100),
corpmode nvarchar(20),
bizaddr nvarchar(100),
viewhits int ,
mainproduct nvarchar(200),
tel nvarchar(30),
fax nvarchar(15),
Des nvarchar(600),
Rank INT
)
/********ANY-WORDS SEARCH******/
IF @AllWords=0
INSERT INTO @Temcompany
SELECT areacode,
u_name,corpname,corpmode,bizaddr,viewhits,mainproduct,tel,fax,left(des,140),
3*dbo.wordcount(@word1,corpname)+dbo.wordcount(@word1,Des)+
3*dbo.wordcount(@word2,corpname)+dbo.wordcount(@word2,Des)+
3*dbo.wordcount(@word3,corpname)+dbo.wordcount(@word3,Des)+
3*dbo.wordcount(@word4,corpname)+dbo.wordcount(@word4,Des)+
3*dbo.wordcount(@word5,corpname)+dbo.wordcount(@word5,Des)
AS Rank
from company
ORDER BY Rank DESC
/*************all-words search******************/
IF @AllWords=1
INSERT INTO @Temcompany
SELECT areacode,
u_name,corpname,corpmode,bizaddr,viewhits,mainproduct,tel,fax,left(des,140),
(3*dbo.wordcount(@Word1,corpname)+ dbo.wordcount(@word1,Des))*
CASE
WHEN @word2 IS NULL THEN 1
ELSE 3*dbo.wordcount(@word2,corpname)+dbo.wordcount(@word2,Des)
END *
CASE
WHEN @word3 IS NUll THEN 1
ELSE 3*dbo.wordcount(@word3,corpname)+dbo.wordcount(@word3,Des)
END *
CASE
WHEN @word4 IS NULL THEN 1
ELSE 3*dbo.wordcount(@word4,corpname)+dbo.wordcount(@word4,Des)
END *
CASE
WHEN @word5 IS NULL THEN 1
ELSE 3*dbo.wordcount(@word5,corpname)+dbo.wordcount(@word5,Des)
End
AS Rank
FROM company
where areacode like @areacode+'%'
ORDER BY Rank DESC
/**********在外部变量保存搜索结果数**************/
SELECT @HowManyResults=COUNT(*)
From @Temcompany
where Rank >0
/*****************按页返回结果****************************/
SELECT * FROM @Temcompany where Rank>0
and RowNumber > (@PageNumber -1)* @PerPage
and RowNumber <= @PageNumber * @PerPage
ORDER BY Rank DESC
END
其中AllWords是起一个开关的作用,使用时,根据需要改变,在这里没有添加什么扩展,有兴趣的看官,可以试着改造一下,或扩展一下,由于时间的关系,我没有做过多的说明,如有兴趣探讨,可以联系我!

浙公网安备 33010602011771号