动态网站制作指南 [  QQ表情  ]
[ 投票调查 ]
[ 企业邮箱 ]
[ 网站空间 ]
网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
ASP源码 | .Net源码 | PHP源码 | JSP源码 | JAVA源码 | CGI源码 | VB源码 | C++源码 | Delphi源码 | PB源码 | VF源码 | 汇编 | 服务器
电脑书籍下载:程序设计书籍 | 数据库教程书籍 | 平面与多媒体书籍 | 网络通讯书籍 | 系统管理书籍 | 网络安全书籍 | 认证考试书籍
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > 数据库学院 > 数据库技巧
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
数据库:数据库教程,数据库技巧,Oracle教程,MySQL教程,Access教程,DB2教程,数据库安全,数据库文摘
文章搜索服务
邮件订阅
输入你的邮件地址,
你将不会错过任何关于:
[ 数据库技巧 ]的信息



本月文章推荐
.sql 2005 express 远程访问和sa密.
.不通过dsn访问sql server.
.在数据库里取前10条数据.
.数据库查询结果的动态排序(5).
.查询Sql server数据死锁和阻塞的.
.用SQL一次插入多条数据.
.SQL Server数据对象结构的动态建.
.32位到64位的sql server移植.
.日志方式转换及物理日志和逻辑日.
..NET 2.0 SqlDependency快速上手.
.SELECT查询的应用(二).
.SQL Server Express 数据库自动部.
.SQL Server 2008的新压缩特性.
.Xp下安装SQL2000或者其他软件系统.
.SQL Server: convert varbinary .
.剖析SQL Server 2005中的报告服务.
.Sql server安装2005中AdventureW.
.SQLServer分页查询通用存储过程.
.一种处理不规范日期数据的好方法.
.在SQL Server所在的计算机上运行.

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

发表日期:2006-11-17 |


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

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

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

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

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

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

 

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

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

 


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

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

 

二、参数传递

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

 

三、搜索的实现过程

 

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

Any-World Search实现如下:

 


 1SELECT 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
 9FROM Product
10
11
 

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

 

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

 


 1SELECT 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
17FROM Product
18

    这时把每个关键词出现的次数相乘只要一个没出现RANK就为0,为0就是搜索结果为空。

还可以这样实现:

 


 1SELECT 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
12FROM Product
对没出现的关键词赋值-1000,这样Rank就肯定为负数,负数表示搜索结果为空。

 

 

四、对结果进行分页

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

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

 

五、完整代码

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

 


  1CREATE 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)
 12AS
 13/**//* 创建临时表,保存搜索的结果(Sql Server2005适用,Sql Server2000见如何在数据层分页以提高性能) */
 14DECLARE @Products TABLE
 15(RowNumber SMALLINT IDENTITY (1,1) NOT NULL,
 16 ID INT,
 17 Name VARCHAR(50),
 18 Description VARCHAR(1000),
 19Rank INT)
 20
 21/**//* Any-words search */
 22IF @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
 42IF @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
 58Description)
 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
 68Description)
 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
 78Description)
 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
 88Description)
 89
 90          END
 91
 92          AS Rank
 93
 94   FROM Product
 95
 96   ORDER BY Rank DESC
 97
 98/**//* 在外部变量保存搜索结果数 */
 99
100SELECT @HowManyResults = COUNT(*)
101
102FROM @Products
103
104WHERE Rank > 0
105
106/**//* 按页返回结果*/
107
108SELECT ProductID, Name, Description, Price, Image1FileName,
109
110 Image2FileName, Rank
111
112FROM @Products
113
114WHERE Rank > 0
115
116  AND RowNumber BETWEEN (@PageNumber-1) * @ProductsPerPage + 1
117
118                    AND @PageNumber * @ProductsPerPage
119ORDER BY Rank DESC
 

至此一个简单的搜索算法就实现了。


上一篇:分页存储过程2000 人气:6286
下一篇:SQL server 2005的表分区 人气:6101
浏览全部SQL Server 2005的内容 Dreamweaver插件下载 常用网页广告代码全集
  最新网站源码 最新软件下载
2008-7-5 360安全卫士 V4.2.0.1004
2008-7-5 PHPDug v2.0 多国语言版
2008-7-5 乘风电影程序 v3.69 (SQL)
2008-7-5 乘风电影程序 v3.69
2008-7-5 wfTextImage文字图像组件 v1.5
2008-7-5 ZY music! v1.1.0705
2008-7-5 FavShop网店系统 v1.0
2008-7-4 天空网络电影系统SKYUC v2.5.1 B
2008-7-4 Drupal v7.x-dev Build 080704
2008-7-5 AgileMessenger即时通讯工具 v1.
2008-7-5 GoodCalculator2.0版固件计算器
2008-7-5 RepoName源地址搜索工具 v1.21b
2008-7-5 AgileMessenger即时通讯工具 v1.
2008-7-5 TouchCopy多媒体管理软件 v3.13完
2008-7-5 VideosTone视频铃声 v1.1汉化破解
2008-7-5 TouchPad触摸板 v4.44破解版
2008-7-5 VideosTone破解补丁 v1.0
2008-7-5 Feeds GoogleReader客户端 v0.4.3


  发表评论
姓 名: 验证码:
内 容:
[ 汉字翻译拼音 ] [ 广告代码 ] [ 符号对照表 ] [ 进制转换 ] [ 经典小工具 ] [ 个税计算 ] [ 汉字简繁转换 ] [ 普通单位换算 ] [ 公制单位换算 ]
[ 生辰老黄历 ] [ 国内电话区号 ] [ 国家代码与域名缩写 ] [ 文字加密解密 ] [ 健康查询 ] [ 万年历 ] [ 手机号码查询 ] [ ip搜索 ] [ Google PR查询 ]
业务联系 | 广告刊登 | 频道合作 | 投稿荐稿 | 联系方式 | 加入收藏 | RSS订阅
Copyright © 2000-2008 www.knowsky.com All rights reserved | 网络实名:动态网站制作指南 | 沪ICP备05001343号
ホームページ制作 不動産検索システム 求人情報