基于Asp 的Web数据库多条件数据查询通用程序设计
2012-09-07刘龙飞
刘龙飞
(渭南师范学院教务处,陕西渭南714000)
基于Asp 的Web数据库多条件数据查询通用程序设计
刘龙飞
(渭南师范学院教务处,陕西渭南714000)
通过对当前数据库查询设计思路和设计方法的分析,提出将数据库和数据表名称作为参数,利用Adox对象读取字段名、字段类型、字段说明等数据赋值给列表框控件,使用选择输入和键盘输入相结合的方式构建SQL语句条件表达式,从而达到数据查询目的,提供了一种基于Asp的Web数据库多条件数据查询通用程序的设计方案和实现方法.
Asp;Web数据库;Adox对象;数据查询;程序设计
0 引言
随着Internet的进一步发展和动态网页技术的日益成熟,各种Web数据库应用相继而生,而数据查询是用户通过Web数据库获取信息的重要途径之一,也是各种数据库程序设计的重点.用户希望能方便有效快速地找到他们所需的信息,为各种事务处理提供有力的支持.所以,数据查询作为基于Web数据库应用软件设计中实现的一项重要功能,必须具有良好的数据界面和方便的操作以及灵活的查询功能,这也是软件开发人员所追求的目标.
在过去的数据查询设计方面,开发者往往是采用较单一的或程式化的查询功能,对用户所查询的数据只是固定在某个字段或多个字段中,字段是开发者提前预设好的,通常是设置固定的数据库和数据表,通过构建SQL语句来实现数据查询,这样就会形成针对不同的数据表、不同的字段,开发者需编写相似的代码来实现相同功能的查询,这样花费大量的精力和时间却完成的是同样的工作,如果能把数据库表文件的选择、查询结果输出字段的选定、不定数量查询条件的输入、条件表达式中数据类型的匹配及查询结果的输出等操作融为一体,设计在一个通用型的查询程序中,则查询设计将变得非常方便灵活而且简单.鉴于此,本文以Asp+Access应用为例,提出将数据库和数据表名称作为参数,利用Adox对象读取数据表中的字段名、字段类型、字段说明等数据赋值给列表框控件,通过Asp框架技术实现存放数据库表字段名称的列表框控件级联更新来实现SQL语句条件表达式的构建,从而达到数据查询的目的.
1 程序设计及关键技术
1.1 程序设计思路
为了使查询程序具有良好的交互功能和操作方便,在此查询程序中,通过变量参数传递查询数据库(设为Mydb)和数据表(设为Mytable)名称,用户在选择字段项的列表框控件(设为Myfiled)中选定要查询的条件字段,在选择关系运算符(>、<、=、Like、$等)的列表框中选择字段值与查询值之间的关系,在查询值文本框控件(Mytextbox)中输入具体的值来进行查询操作,亦可在根据用户选择的字段Myfiled在表Mytable中查询不重复的字段Myfield的值(设为Myvalue)的列表框控件中进行选择.根据这样的流程可以设定多个列表框实现查询条件的设定.对多个查询条件的关系设定逻辑运算符“AND”、“OR”、“NOT”来实现,条件的多少将根据数据表中字段的多少来定,查询标准表达的生成用循环读取列表框控件的值来实现,将数据表字段类型的值赋值给另一个隐藏属性的列表框控件(设为Myfieldtype)后,根据字段列表框控件Myfield的选项索引值与Myfieldtype的选项索引值进行匹配得到选定Myfield的字段类型值,然后进行输入查询条件值的数据类型判断,进而构建SQL语句进行查询.图1为数据表仅有两个字段的查询.
图1 数据表中仅有2个字段的查询界面
1.2 设计中使用的关键技术
1.2.1 数据表字段名、字段类型及字段说明的读取
在程序设计中,使用列表框控件来列举字段名,因为大部分的数据表结构设计中使用英文进行字段名的设定,此为方便程序代码的编写,而对字段名的具体中文解释说明则在数据表设计的字段说明中设定,因此在此通用程序中我们要提取字段的中文说明,这里使用Asp中VBscript对数据库的驱动操作和表对象操作.
(1)通过Ado连接数据库[1]
使用Ado连接数据库是DSN中比较先进的一种数据库访问技术,在Asp编程中,利用Ado可以连接数据库、操作数据库,并可以对多种数据库进行连接操作.对Access数据库而言,由于一个文件就是一个数据库,所以可以直接利用Asp程序中的语法作链接,通过建立可与数据库交换数据的对象Connection和使用Execute方法执行SQL语句来完成对数据源的操作.语法如下:
Set connection=Sever.Createobject("adodb.connection")
Dbpath=Sever.Mappath("database/*.mdb")
Connection.open"drive={Microsoft Access Driver(*.mdb)};dbp="&Dbpath
将数据库和数据表名称设为参数时的代码如下:
Set connection=Sever.Createobject("adodb.connection")
Dbpath=Sever.Mappath(数据库变量名)
Connection.open"drive={Microsoft Access Driver(*.mdb)};dbp="&Dbpath
SQL="select* from"&数据表变量名
(2)字段名、字段类型及字段说明的读取
在Asp中,对数据表结构的读取操作,主要通过Recordset对象提供的Fields数据集合中的field数据字段对象来完成.Fields数据集合对象拥有很多的方法与属性,其中有Item方法(用来取得Fields数据集合中所包含的所有filed对象),它的语法为:Set myfield=fields.Item(Index)或Set myField=Fields.(Index);Count属性(取得当前Recordset对象记录集合中的字段数量);Name属性(取得当前Recordset对象记录集合中的字段名称);Type属性(取得Recordset对象记录集合中的字段的数据类型)[2];如果仅为数据表中字段名、字段类型等数据的提取,我们即可用rs.fields.item(i).name和rs.fields.item(i).type(此取得的值为一具体的数值,具体说明见表1)完成,但要提取数据表中字段说明部分的内容,并且要知道具体的字段数据类型的含义就难以胜任了.这里通过Adox对象和编写专门的说明函数来完成此项工作.[2]Adox对象包含许多对象、方法和属性,这里我们用到Catalog对象(包含描述数据源模式目录的集合)、Table对象(表示数据库表,包括列、索引和关键字)、Column对象(表示表、索引或关键字的列)、ActiveConnection属性(指示目录所属的Ado Connection对象).Adox对象的引用和其对象、属性的语法为:set mydb =server.createobject("adox.catalog");set mytable=server.createobject("adox.table");set myfield=server.createobject("adox.column");MyDB.ActiveConnection=conn.[1]
表1 Access数据库常见的字段数据类型
1.2.2 基于Asp框架(Frame)技术的列表框控件数据的级联更新
(1)采用框架结构技术的理由
对于多个列表框控件的数据的相互关联,肯定是第一个的数据值是其他的条件,复杂一点,一个以其他几个的数据值作为条件进行数据筛选,而所有的数据的筛选操作都必须有服务器端执行.如果页面的数据量很大或控件数量比较大,那么提交所带来的最大的问题就是时间的延迟,如果网络速度不理想,就会出现提交一次页面要花费好长时间或出现超时操作.另外,如果用户页面还有其他的控件如文本框等,假设用户在未进行列表框选择操作之前进行了文本框数据的输入工作,所要完成我们列表框控件数据更新的页面提交操作很有可能使用户对文本框的输入操作变成徒劳,也就是说文本框控件的值会变成输入之前的状态.所以采用了框架之间的通信技术来实现不同下拉式列表框控件之间的相互数据关联.
(2)框架的定义和通讯机制
框架Frame最主要功用是“分割”视窗,使每个“小视窗”能显示不同的HTML文件,不同框架之间可以互动,也就是说不同框架之间可以交换讯息与资料.当加载一个一般的HTML文档到浏览器,创建浏览器中的一个模型,这个浏览器始于窗口对象和它包含的文档,层次模型顶部地位相当简单.如果是框架设置(framesetting)文档加载到一个浏览器,这个浏览器就会建立一个稍微不同的层次模型.该模型的精确结构完全依靠子框架设置文档中定义的框架结构.
框架可以将屏幕分割成不同的区域,每个区域有自己的URL,通过Frames[]数组对象来实现不同框架之间的访问通讯.实际上框架对象本身也是一个窗口,它继承了窗口对象的所有特征,并拥有所有的属性和方法.框架设置建立一个集中框架间的关系.由于是从面向对象功能的编程领域借用的术语,这个框架设置文档加载到Parent窗口,定义为父窗口文档的每个框架是child框架.可以给每个frame一个“名字”(name).frame的名字在JavaScript语法中的地位非常重要.一个script引用需要有三个可能的路程之一,这也是框架之间的通讯路径,它们是到目前为止所描述的两代层次:父到子,子到父或子到子.[3]
这些窗口间的通讯路径需要不同的引用风格.下面就描述一下不同路径之间的script引用脚本.
1)父到子引用[3]
从父方看,它包括两个以上的框架,这些框架作为框架对象数组也被存在模型中.可以通过数组语法或者通过在<FRAME>标记符的NAME属性赋给的名字通知一个框架.这里以ObjName代替了我们试图访问的对象,一个从父到子框架的引用模型如下:
[window.]frames[n].ObjName;[window.]framename.ObjName
框架的索引值基于出现在框架设置文档的<frame>标记符中的顺序.
2)子到父引用[3]
从子的角度看,下一层升个层次被称为parent.因此,引用到那层的项是简单的:
parent.ObjName
3)子到子引用[3]
任何窗口或者框架的属性之一就是它的parent,因此必须引用这个属性来处理框架之间通信的方法,因此,从一个子到它的同属之一时,就可以引用下面的格式.
Parent.frames[n].ObjName;Parent.frame.ObjName
(3)列表框控件数据的级联更新[4]
采用级联的形式进行,逐级对列表框中所需数据进行条件筛选,主要采用javascript定义函数来完成,这里定义一个是clearlist(list),通过window.parent.eval(list).options[0]=null对列表框控件中每个项进行赋值NULL操作来完成对整个列表框控件进行清空操作,参数list是要清空的控件对象名称,另一个是addnewoption(othe,selectname),主要通过new Option(othe1,othe2,"true","true")命令来添加每个子项来赋指定值完成对指定的对象(selectname)进行数据添加操作,添加时对要添加的数据值othe1,othe2和控件的已有值进行对比添加.此用了框架技术中子父窗口数据的调用,即parent.objectname.核心代码如下:
<script type="text/javascript">
Function clearlist(list){
while(window.parent.eval(list).options.length>0){
window.parent.eval(list).options[0]=null;
}
}
Function addnewoption(othe1,othe2,selectname){
if(window.parent.eval(selectname).value==othe2){
return false;
}
var select1=window.parent.eval(selectname);
var opt=new Option(othe1,othe2,"true","true");
select1.options.add(opt,0);
}
</script>
1.2.3 通用查询程序的核心设计
(1)列举数据表结构列表框的赋值操作
对列举数据表结构列表框Listbox1的赋值操作,主要是考虑此控件中Value值和显示值的对应及是否相同的问题,对字段名为英文,字段说明为中文的情况使用字段说明为显示值,控件的Value值为字段名,而对没有字段说明或字段说明为空的情况则使用显示值和Value值同为字段名,这里仅以字段名为英文,字段说明为中文的情况进行代码说明.核心代码为:
response.write"<script>clearlist('Listbox1');</script>"//对列表框控件进行清空处理
For Each MyTable In MyDB.Tables
if mytable.name=table1 then//table1为表变量名
For Each MyField In MyTable.Columns
For Each pro In MyField.Properties
if pro.name="Description"and pro.Value<>""then
response.write"<script>addnewoption('"&MyField.name&"','"&pro.Value&"','Listbox1')</script>"
end if
Next
Next
end if
Next
(2)数据库表字段类型数据的存取
在对数据表字段名称和字段说明数据进行列表框控件Myfield赋值操作时,同时对与之相对应的存放字段类型数据的列表框控件Myfieldtype进行赋值,这样它们将会依据列表框控件的选项索引值进行一一对应,在进行Myfield列表框控件选定数据值时,通过Myfield.selectedIndex来提取Myfield的索引值,根据其索引值选定字段类型列表框控件Myfieldtype的相应选项值,通过Myfieldtype.options[Index].value来取得其值.
(3)数据类型的匹配问题
在基于Asp的Web应用程序中,查询程序在执行过程中,往往会因为构建的SQL语句中标准表达式的数据类型不匹配而出现“Microsoft OLE DB Provider for ODBC Drivers(0x80040E07);[Microsoft][ODBC Microsoft Access Driver]标准表达式中数据类型不匹配”的出错信息[5].因此,在程序设计时对文本框控件的输入数据类型要做相应的设置和数据类型的判定,如果是用户通过列表框控件进行选择输入的数据,使用列表框控件的Onchange方法和Javascript实现,具体代码为:Onchange="document.all.Mytextbox.value =this.value",这时一般不会出现错误,但如果是用户通过键盘输入的就有可能.解决方案是通常使用文本框控件的Onblur事件(用于当Blur事件(即失去焦点事件)发生时执行的Javascript代码)和OnkeyUp事件调用预先设定的Javascript函数来实现.这里的OnkeyUp事件用来判定用户是否按下Enter(回车)键,OnkeyUp="if(event.keyCode==13){Js函数}".那么是VBscript中构建SQL语句时,标准表达式数据变量依其类型不同而使用不同的定界符,所以在文本框控件的Onblur事件和OnkeyUp事件发生时,给文本框控件的Value属性要添加相应的数据类型定界符,否则在查询操作过程中将产生数据类型不匹配的错误而得不到所需要的数据.在使用列表框控件Listbox1的字段名值时,我们要同时取得与其对应的字段类型值,这里采用一种隐藏类型的文本框控件来存取其字段类型值(<Input type=hidden name="filedtype">),对此文本框控件Fieldtype的赋值及调用时要添加定界符,数据为字符型,加上定界符'',数据类型为日期型,使用Cdate()函数进行转换,数值型可直接应用.
对于根据列表框控件List1选择的查询字段的数据类型可以用myfield.type提取常数值,并将其赋值给隐藏文本框控件filedtype,然后通过以下函数Mytextbox1(常数值)对查询值文本框Mytextbox进行匹配赋值处理,以下代码仅适用于字符型、数值型、日期型字段,其他的依此类推.
<script language=javascript>
Function Mytextbox1(a){
If(a==202||a==203){
document.all.Mytextbox.value="'"+document.all.Mytextbox.value+"'";
}else{
If(a==7){
document.all.Mytextbox.value=str2date(document.all.Mytextbox.value);
}else{
document.all.Mytextbox.value=document.all.Mytextbox.value;
}
}
}
//以下为字符型转换为日期型数据函数
Function str2date(str){
var d=null;
var reg=/^(d{4})-(d{2})-(d{2})(d{2}):(d{2}):(d{2}).(d+)$/
if(arr=str.match(reg))d=new date(number(arr[1]),number(arr[2])-1,number(arr[3]),number (arr[4]),number(arr[5]),number(arr[6]),number(arr[7]))
return d;
}
</script>
(4)查询条件标准表达式的构建
在完成查询之前,需要构建SQL语句在数据表中进行数据的筛选查询,列举出所有符合查询条件的记录,那么SQL语句的查询条件标准表达式的如何生成是需解决的问题.本程序中采用For each…In…Next循环读取页面中的每个列表框控件的值来进行标准查询表达式的组合生成,将生成的查询表达式保存在一个变量中,从而完成SQL语句的构建.
1.3 查询结果的显示
在现有的Web应用程序的数据查询显示页面中,一般习惯于使用表格形式来显示数据,因此,在查询到数据结果后,使用<table>进行查询结果的输入显示,这就需考虑表格的表头和内容的设置,这里我们调用上述读取数据表结构代码中设定的pro.Value来将字段的说明设为表头,这是因为大部分数据表的字段用英文来设置,如果数据表结构中的字段说明为空,那只有设置表头为字段名MyField.name了,对字段说明是否为空用If…End If语句进行判断即可.表格中内容的输出则更加容易,第i列显示第I个字段用RS(I)即可.查询结果如表2:
表2 查询结果示例
2 结语
本文详细说明了基于Asp的Web应用程序中数据表查询通用程序设计的思路和核心代码设计,在Adox对象的数据表字段名、字段类型、字段说明等数据的读取,基于Asp框架(Frame)技术的列表框控件数据的级联更新,数据类型的匹配等问题的解决及查询结果的输出等方面提出了一些新的想法和技术,这些都是从简化查询操作及提高查询的灵活性等要求为出发点.当然本文中对字段值的列举通过列表框控件实现,亦可通过创建根据用户输入的字符在自动提示文本框控件来查找实现,此方法是在用户输入时会检测输入的头几个字符,然后给出一个可帮助用户输入的单词列表.这种方法也比较实用方便.以上论述仅对单表查询进行说明,对于多表查询、分组查询及计算没有说明,若要进行复杂操作,还需做进一步的研究.
[1]吕继迪,孙明丽,庞娅娟.ASP程序开发范例宝典[M].第2版.北京:人民邮电出版社,2009.
[2]何国民,仲治国.ASP动态网站:68个典型模块精解[M].北京:科学出版社,2009.
[3]明日科技.ASP.NET项目开发案例全程实录[M].北京:清华大学出版社,2011.
[4][美]Danny Goodman.JavaScript宝典[M].汪厚祥,董京春,杨霞,等译.北京:电子工业出版社,2000.
[5]李春葆,曾平,喻丹凡.ASP动态网页设计:基于Access数据库[M].北京:清华大学出版社,2009.
【责任编辑 曹 静】
On General Program Design of Multi-conditioned Query Based on Web Database of ASP
LIU Long-fei
(Weinan Normal University,Weinan 714000,China)
The paper analyzes the idea and method of the present database query design and advances the database and table names as the parameters,while using the object Adox to read the field names,field data types,field instructions and other field assignments to the filedlist controls.Furthermore,random input and keyboard input combined to construct the Sql statements to gain the data query.Therefore,the paper achieves the general program design of multi"conditioned query based on web database of ASP.
Asp;Web database;the object Adox;data query;program design
book=0,ebook=50
TP311
A
1009—5128(2012)06—0068—06
2012—04—12
渭南师范学院科研计划项目(11YKZ052)
刘龙飞(1977—),男,陕西岐山人,渭南师范学院教务处高级工程师,理学硕士.研究方向:数据库原理及其应用.