选择显示字体大小

基于asp的站内多值搜索

运行环境:iis
脚本语言:vbscript
数据库access/sql server
数据库语言:sql
 
1.概要:
不论是在论坛,还是新闻系统,或是下载系统等动态网站中,大家经常会看到搜索功能:搜索帖子,搜索用户,搜索软件(总之搜索关键字)等,本文则是介绍如何建立一个高效实用的,基于asp的站内多值搜索。

本文面对的是“多条件模糊匹配搜索”,理解了多条件的,单一条件搜索也不过小菜一碟了。一般来讲,有两种方法进行多条件搜索:枚举法和递进法。搜索条件不太多时(n<=3),可使用枚举法,其语句频度为2的n次方,成指数增长,n为条件数。很明显,当条件增多以后,无论从程序的效率还是可实现性考虑都应采用递进法,其语句频度为n,成线性增长。需要指出的是,枚举法思路非常简单,一一判断条件是否为空,再按非空条件搜索,同时可以利用真值表技术来对付条件极多的情况(相信没人去干这种事,4条件时就已经要写16组语句了);递进法的思想方法较为巧妙,重在理解,其巧就巧在一是使用了标志位(flag),二是妙用sql中字符串连接符&。下面以实例来讲解引擎的建立。

2.实例:
我们建立一通讯录查询引擎,数据库名为addressbook.mdb,表名为address,字段如下:

id
name
tel
school
1
张 三
33333333
电子科技大学计算机系
2
李 四
44444444
四川大学生物系
3
王 二
22222222
西南交通大学建筑系


web搜索界面如下:

姓名:
电话:
学校:
搜索按钮


采用枚举法的源程序如下:
<%@ codepage = "936" %>
'连接数据库
<%
dim conn
  dim dboath
dim rs
dim sql
  set conn=server.createobject("adodb.connection")
  dbpath = server.mappath("addressbook.mdb")
  conn.open "driver={microsoft access driver (*.mdb)};dbq=" & dbpath
set rs=server.createobject("adodb.recordset")
'从web页获取姓名、电话、学校的值
dim name
dim tel
dim school
name=request("name")
tel=request("tel")
school=request("school")
'枚举法的搜索核心,因为有3个条件所以要写8组if判断语句
  if trim(name)="" and trim(tel)="" and trim(school)="" then
     sql="select * from address order by id asc"
  end if
  if trim(name)="" and trim(tel)="" and trim(school)<>"" then
     sql="select * from address where school like '%"&trim(school)&"%' order by id asc"
  end if
  if trim(name)="" and trim(tel)<>"" and trim(school)="" then
     sql="select * from address where tel like '%"&trim(tel)&"%' order by id asc"
  end if
  if trim(name)="" and trim(tel)<>"" and trim(school)<>"" then
     sql="select * from address where tel like '%"&trim(tel)&"%' and school like '%"&trim(school)&"%' order by id asc"
  end if
  if trim(name)<>"" and trim(tel)="" and trim(school)="" then
     sql="select * from address where name like '%"&trim(name)&"%' order by id asc"
  end if
  if trim(name)<>"" and trim(tel)="" and trim(school)<>"" then
     sql="select * from address where name like '%"&trim(name)&"%' and school like '%"&trim(school)&"%' order by id asc"
  end if
  if trim(name)<>"" and trim(tel)<>"" and trim(school)="" then
     sql="select * from address where name like '%"&trim(name)&"%' and tel like '%"&trim(tel)&"%' order by id asc"
  end if
  if trim(name)<>"" and trim(tel)<>"" and trim(school)<>"" then
     sql="select * from address where name like '%"&trim(name)&"%' and tel like '%"&trim(tel)&"%' and school like '%"&trim(school)&"%' order by id asc"
  end if
rs.open sql,conn,1,1
'显示搜索结果
if rs.eof and rs.bof then      
     response.write "目前通讯录中没有记录"
else
   do while not rs.eof
      response.write "姓名:"&rs("name")&"电话:"&rs("tel")&"学校:"&rs("school")&"<br>"
      rs.movenext
   loop
end if
'断开数据库
set rs=nothing        
  conn.close     
  set conn=nothing
%>

理解上述程序时,着重琢磨核心部分,8组语句一一对应了3个搜索框中的8种状态

name
tel
school
非空
非空
非空
非空
非空
非空
非空
非空
非空
非空
非空
非空


另外trim()是vb的函数,将输入的字符串前后的空格去掉;%是sql语言中的多字符通配符(_是单字符通配符),由此可见%"&trim()&"%对搜索框中输入的关键字是分别向左向右匹配的;sql语言中用and连接说明非空条件之间是“与”关系。
 
再来看看递进法,与枚举法相比它们只有核心部分不同:
'递进法的搜索核心,依次判断条件为空否,非空则将其加入搜索条件
sql="select * from address where"
if name<>"" then
sql=sql&" name like '%"&name&"%' "
  flag=1
end if
if tel<>"" and flag=1 then
sql=sql&" and tel like '%"&tel&"%'"
flag=1
elseif tel<>"" then
sql=sql&" tel like '%"&tel&"%'"
flag=1
end if
if company<>"" and flag=1 then
sql=sql&" and company like '%"&company&"%'"
flag=1
elseif company <>"" then
sql=sql&" company like '%"&company&"%'"
flag=1
end if
if flag=0 then
   sql="select * from address order by id asc"
end if
rs.open sql,conn,1,1

递进法是一个明智的算法,单从语句的长短就可以看出来了。这个算法的难点和精髓就在flag和&上。首先你应该清楚&在sql中就是一个字符串连接符,把该符号左右的字符拼接在一起。再回到程序,当name不为空时sql="select * from address where name like '%"&name&"%' "同时flag=1;接下来当name不为空时且tel不为空时,即tel<>"" and flag=1时,sql="select * from address where name like '%"&name&"%' and tel like '%"&tel&"%' "同时flag=1,否则当name为空tel不为空,sql="select * from address where tel like '%"&tel&"%' "同时flag=1;以此类推就可以推广到n个条件的搜索。当然条件皆为空时,即flag=0将选择所有表中所有项。

3.验证:

至此,一个搜索引擎就建立起来了。以下是一些使用示例:

姓名:张
电话:
学校:
搜索按钮

 
搜索结果为:
姓名: 张三 电话:33333333 单位:电子科技大学计算机系
 

姓名:
电话:
学校:大学
搜索按钮

 
搜索结果为:
姓名:张三 电话:33333333 单位:电子科技大学计算机系
姓名  李 四 电话:44444444 单位:四川大学生物系
姓名:王二 电话:22222222 单位:西南交通大学建筑系

姓名:
电话:4444
学校:四川
搜索按钮

 
搜索结果为:
姓名  李 四 电话:44444444 单位:四川大学生物系

姓名:
电话:
学校:交%大
搜索按钮

 
搜索结果为:
姓名:王二 电话:22222222 单位:西南交通大学建筑系

4.改进:
其实这个引擎还有些缺陷,问题主要在于通配符%。一方面是因为人们平时习惯把*作为通配符,另一方面%若出现在超链接中,通过request获取时%将被“吃”掉,如下:

--test.htm--
…    
<a href=test.asp?content=test%the%sign>click here</a>


--test.asp--
<%
content=request(“content”)
response.write content
%>

在ie中浏览test.htm时点击超链接,显示为:
testthesign
可见%直接被超链接忽略掉了。怎么才能解决这个问题呢?很简单,我们做点小小的手脚--偷梁换柱。
将以下代码加在搜索核心之前:
name=replace(name,"*","%")
tel=replace(tel,"*","%")
company=replace(company,"*","%")
将以下代码加在搜索核心之后:
name=replace(name,"%","*")
tel=replace(tel,"%","*")
company=replace(company,"%","*")
在我们来分析一下这些语句。replace()是vb中字符串替换函数,replace(name,"*","%") 就是将name中所有的*换成%。也就是说,我们把3个条件中凡是出现的*都替换为%,这样一来前3句就将通配符改成*了。而后3句就可以防止%被“吃”掉。所有问题就迎刃而解了吧。

姓名:
电话:
学校:交%大
搜索按钮


搜索结果为:
姓名:王 二 电话:22222222 单位:西南交通大学建筑系

将上面的语句再改一改,把*用空格代替,不就成了我们在google、baidu中常用的用空格来分开搜索条件的搜索引擎了吗?

运行环境:iis
脚本语言:vbscript
数据库access/sql server
数据库语言:sql
 
1.概要:
不论是在论坛,还是新闻系统,或是下载系统等动态网站中,大家经常会看到搜索功能:搜索帖子,搜索用户,搜索软件(总之搜索关键字)等,本文则是介绍如何建立一个高效实用的,基于asp的站内多值搜索。

本文面对的是“多条件模糊匹配搜索”,理解了多条件的,单一条件搜索也不过小菜一碟了。一般来讲,有两种方法进行多条件搜索:枚举法和递进法。搜索条件不太多时(n<=3),可使用枚举法,其语句频度为2的n次方,成指数增长,n为条件数。很明显,当条件增多以后,无论从程序的效率还是可实现性考虑都应采用递进法,其语句频度为n,成线性增长。需要指出的是,枚举法思路非常简单,一一判断条件是否为空,再按非空条件搜索,同时可以利用真值表技术来对付条件极多的情况(相信没人去干这种事,4条件时就已经要写16组语句了);递进法的思想方法较为巧妙,重在理解,其巧就巧在一是使用了标志位(flag),二是妙用sql中字符串连接符&。下面以实例来讲解引擎的建立。

2.实例:
我们建立一通讯录查询引擎,数据库名为addressbook.mdb,表名为address,字段如下:

id
name
tel
school
1
张 三
33333333
电子科技大学计算机系
2
李 四
44444444
四川大学生物系
3
王 二
22222222
西南交通大学建筑系


web搜索界面如下:

姓名:
电话:
学校:
搜索按钮


采用枚举法的源程序如下:
<%@ codepage = "936" %>
'连接数据库
<%
dim conn
  dim dboath
dim rs
dim sql
  set conn=server.createobject("adodb.connection")
  dbpath = server.mappath("addressbook.mdb")
  conn.open "driver={microsoft access driver (*.mdb)};dbq=" & dbpath
set rs=server.createobject("adodb.recordset")
'从web页获取姓名、电话、学校的值
dim name
dim tel
dim school
name=request("name")
tel=request("tel")
school=request("school")
'枚举法的搜索核心,因为有3个条件所以要写8组if判断语句
  if trim(name)="" and trim(tel)="" and trim(school)="" then
     sql="select * from address order by id asc"
  end if
  if trim(name)="" and trim(tel)="" and trim(school)<>"" then
     sql="select * from address where school like '%"&trim(school)&"%' order by id asc"
  end if
  if trim(name)="" and trim(tel)<>"" and trim(school)="" then
     sql="select * from address where tel like '%"&trim(tel)&"%' order by id asc"
  end if
  if trim(name)="" and trim(tel)<>"" and trim(school)<>"" then
     sql="select * from address where tel like '%"&trim(tel)&"%' and school like '%"&trim(school)&"%' order by id asc"
  end if
  if trim(name)<>"" and trim(tel)="" and trim(school)="" then
     sql="select * from address where name like '%"&trim(name)&"%' order by id asc"
  end if
  if trim(name)<>"" and trim(tel)="" and trim(school)<>"" then
     sql="select * from address where name like '%"&trim(name)&"%' and school like '%"&trim(school)&"%' order by id asc"
  end if
  if trim(name)<>"" and trim(tel)<>"" and trim(school)="" then
     sql="select * from address where name like '%"&trim(name)&"%' and tel like '%"&trim(tel)&"%' order by id asc"
  end if
  if trim(name)<>"" and trim(tel)<>"" and trim(school)<>"" then
     sql="select * from address where name like '%"&trim(name)&"%' and tel like '%"&trim(tel)&"%' and school like '%"&trim(school)&"%' order by id asc"
  end if
rs.open sql,conn,1,1
'显示搜索结果
if rs.eof and rs.bof then      
     response.write "目前通讯录中没有记录"
else
   do while not rs.eof
      response.write "姓名:"&rs("name")&"电话:"&rs("tel")&"学校:"&rs("school")&"<br>"
      rs.movenext
   loop
end if
'断开数据库
set rs=nothing        
  conn.close     
  set conn=nothing
%>

理解上述程序时,着重琢磨核心部分,8组语句一一对应了3个搜索框中的8种状态

name
tel
school
非空
非空
非空
非空
非空
非空
非空
非空
非空
非空
非空
非空


另外trim()是vb的函数,将输入的字符串前后的空格去掉;%是sql语言中的多字符通配符(_是单字符通配符),由此可见%"&trim()&"%对搜索框中输入的关键字是分别向左向右匹配的;sql语言中用and连接说明非空条件之间是“与”关系。
 
再来看看递进法,与枚举法相比它们只有核心部分不同:
'递进法的搜索核心,依次判断条件为空否,非空则将其加入搜索条件
sql="select * from address where"
if name<>"" then
sql=sql&" name like '%"&name&"%' "
  flag=1
end if
if tel<>"" and flag=1 then
sql=sql&" and tel like '%"&tel&"%'"
flag=1
elseif tel<>"" then
sql=sql&" tel like '%"&tel&"%'"
flag=1
end if
if company<>"" and flag=1 then
sql=sql&" and company like '%"&company&"%'"
flag=1
elseif company <>"" then
sql=sql&" company like '%"&company&"%'"
flag=1
end if
if flag=0 then
   sql="select * from address order by id asc"
end if
rs.open sql,conn,1,1

递进法是一个明智的算法,单从语句的长短就可以看出来了。这个算法的难点和精髓就在flag和&上。首先你应该清楚&在sql中就是一个字符串连接符,把该符号左右的字符拼接在一起。再回到程序,当name不为空时sql="select * from address where name like '%"&name&"%' "同时flag=1;接下来当name不为空时且tel不为空时,即tel<>"" and flag=1时,sql="select * from address where name like '%"&name&"%' and tel like '%"&tel&"%' "同时flag=1,否则当name为空tel不为空,sql="select * from address where tel like '%"&tel&"%' "同时flag=1;以此类推就可以推广到n个条件的搜索。当然条件皆为空时,即flag=0将选择所有表中所有项。

3.验证:

至此,一个搜索引擎就建立起来了。以下是一些使用示例:

姓名:张
电话:
学校:
搜索按钮

 
搜索结果为:
姓名: 张三 电话:33333333 单位:电子科技大学计算机系
 

姓名:
电话:
学校:大学
搜索按钮

 
搜索结果为:
姓名:张三 电话:33333333 单位:电子科技大学计算机系
姓名  李 四 电话:44444444 单位:四川大学生物系
姓名:王二 电话:22222222 单位:西南交通大学建筑系

姓名:
电话:4444
学校:四川
搜索按钮

 
搜索结果为:
姓名  李 四 电话:44444444 单位:四川大学生物系

姓名:
电话:
学校:交%大
搜索按钮

 
搜索结果为:
姓名:王二 电话:22222222 单位:西南交通大学建筑系

4.改进:
其实这个引擎还有些缺陷,问题主要在于通配符%。一方面是因为人们平时习惯把*作为通配符,另一方面%若出现在超链接中,通过request获取时%将被“吃”掉,如下:

--test.htm--
…    
<a href=test.asp?content=test%the%sign>click here</a>


--test.asp--
<%
content=request(“content”)
response.write content
%>

在ie中浏览test.htm时点击超链接,显示为:
testthesign
可见%直接被超链接忽略掉了。怎么才能解决这个问题呢?很简单,我们做点小小的手脚--偷梁换柱。
将以下代码加在搜索核心之前:
name=replace(name,"*","%")
tel=replace(tel,"*","%")
company=replace(company,"*","%")
将以下代码加在搜索核心之后:
name=replace(name,"%","*")
tel=replace(tel,"%","*")
company=replace(company,"%","*")
在我们来分析一下这些语句。replace()是vb中字符串替换函数,replace(name,"*","%") 就是将name中所有的*换成%。也就是说,我们把3个条件中凡是出现的*都替换为%,这样一来前3句就将通配符改成*了。而后3句就可以防止%被“吃”掉。所有问题就迎刃而解了吧。

姓名:
电话:
学校:交%大
搜索按钮


搜索结果为:
姓名:王 二 电话:22222222 单位:西南交通大学建筑系

将上面的语句再改一改,把*用空格代替,不就成了我们在google、baidu中常用的用空格来分开搜索条件的搜索引擎了吗?


 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons