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

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情
 现在很多网站都提供了站内的搜索功能,有的很简单在SQL语句里加一个条件如:where names like ‘%words%’就可以实现最基本的搜索了。

 

 
   1.精确搜索,就是把用户输入的各个词语当成一个整体,不分割搜索.
   2.像百度,GOOGLE一样的,按空格把输入的每一个词分离,只要包含这些词语,而不管出现的顺序,称为ALL-Word Search.
   3.对输入的词只要有一个出现就为匹配 称为Any-Word Search

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

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

三、搜索的实现过程

假定我们对Product表进行搜索,Product字段有:Id,Name ,Descripton(产品描述),搜索要同时对Name 和 Description进行。
Any-World Search实现如下:
 
这里对Name赋予权重为3,Description为1(大家根据实际情况赋予不同的权重),Rank是计算列,通过前面定义的UDF计算所关键词出现的次数乘上权重等到的。

同样的All-Word Search实现如下:
 
 
还可以这样实现:

 
 
 四、对结果进行分页
过程简单来说就是创建一个临时表,表中包含行号,读取时按行号来读取数据

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

对没出现的关键词赋值-1000,这样Rank就肯定为负数,负数表示搜索结果为空。
 1 Select  Product.Name, 
 2
 3        ( 3  *  WordCount( @Word1 , Name)  +  WordCount( @Word1 , Description))  *
 4
 5         CASE  
 6
 7            WHEN  @Word2  IS  NULL  THEN  1  
 8
 9              ELSE  3  *  WordCount( @Word2 , Name)  +  WordCount( @Word2 , Description)
10
11         END  *
12
13        
14
15         AS  Rank
16
17 FROM  Product
18

    这时把每个关键词出现的次数相乘只要一个没出现RANK就为0,为0就是搜索结果为空。
 1 Select  Product.Name, 
 2         3  *  WordCount( @Word1 , Name)  +  WordCount( @Word1 , Description)  +
 3
 4         3  *  WordCount( @Word2 , Name)  +  WordCount( @Word2 , Description)  +
 5
 6        
 7
 8         AS  Rank
 9 FROM  Product
10
11
   

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

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

     我们来看看功能强大一点,复杂一点的搜索是如何实现的(在SQL SERVER200/2005通过存储过程实现搜索算法)。
一个SQL Server存储过程实现在表上的模糊搜索 在该表的所有字符串的列上进行比较查找的满足要求的值,如果值中包含有空格,则该值代表两个部分,要查找的结果中只需满足其中一个部分就可以了;空格你也可以自己替换,可以是其他的 具体的改动请看http://blog.csdn.net/lfjfrankie/archive/2009/04/18/4090444.aspx 当然如果可以你也可以自己在代码中改。 立即下载

相关推荐

数据库 带条件查询 SQL

【代码】数据库 带条件查询 SQL

道友 291

SQL存储过程的作用和意义

一、什么是存储过程存储过程 是在大型数据库系统中,一组为了完成特定功能SQL 语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译, 用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象,任何一个设计良好的数据库应用程序都应该用到存储过程。 二、为什么要用存储过程呢? 存储过程真的那么重要吗,它到底有什么好处呢?存储过程说白了就是一堆SQL 的合并。中间加了点逻辑控制。 1.存储过程处理比较复杂的业务时比较实用。具体分为两个方面: (一)响

qq_47776903的博客 4359

Sql Server 存储过程怎么找 存储过程内容

由于之前供应商开发数据仓库,目前已经是屎山代码了,没有文档。需要整理表是从那个存储过程来的,就很麻烦。我的方法最后就是搞了excel 写文档,然后重建数仓。这个是痛苦的过程。用存储过程的技术+sql job 做数仓已经是很老的技术,个人不建议使用。后面我们用Kettle。

小 tom的博客 4493

SQL基本功(一)--SQL和数据库

什么是数据库 将大量数据保存起来,通过计算机加工而成的可以进行高效访问的数据集合称为数据库(Database,DB),将姓名、住址、电话号码、邮箱地址、爱好和家庭构成等数据保存到数据库中,就可以随时迅速获取想要的信息了。用来管理数据库的计算机系统称为数据库管理系统(Database Management System,DBMS。 为什么要使用数据库管理系统(DBMS)来管理数据那? DBMS可以实现多人共享数据 可以提供操作多种大量数据所需要的各种格式 可以应对文件误删、硬盘出...

你隔壁的小王的博客 922

SQL Server 2005存储过程实现高级搜索功能

现在很多网站都提供了站内的搜索功能,有的很简单在SQL语句里加一个条件如:where names like ‘%words%’就可以实现最基本的搜索了。   我们来看看功能强大一点,复杂一点的搜索是如何实现的(在SQL SERVER200/2005通过存储过程实现搜索算法)。   我们把用户的搜索可以分为以下两种:   1.精确搜索,就是把用户输入的各个词语当成一个整体,不分割搜索

lovegod12的专栏 910
上一篇: Oracle Sql优化笔记
下一篇: SQL Server 2000 中使用正则表达式
Octavius
博客等级 码龄22年 25粉丝 27原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值