b>摘 要
文章介绍了基于Web的Browser/Server数据库模式公文发布系统的设计与实现技术,特别是对ASP方式下对数据库的操作进行了比较详细的说明。
关键词 Browser/Server 数据库 ASP ADO
1. 前言
随着Internet应用的不断扩展,许多单位内部都建有Intranet。加快单位内部信息的传送,通过Intranet及时发布、获取单位内部的信息,对于改善和优化单位管理、提高办事效率、提高经济效益会提供有力的支持。为此,我设计和开发了一个适用于单位内部的公文发布系统。这个系统是运行于WinNT平台的基于Browser/Server数据库模式的。这种模式由于其界面简单,适用于不同地点远程访问等特点,近来倍受青睐。一般B/S数据库模式的开发有ASP,API和CGI方式,这里采用ASP方式。
2. 系统的功能
本公文发布系统主要完成三大功能:
1) 用户管理
本系统中的用户分为两类:超级用户、一般用户。其中每位一般用户在做与发布信息相关的操作时是发布人,在做与接收信息相关的操作时是接收人。系统中的超级用户可以随时添加、删除一般用户。一般用户可以随时修改用户个人的信息。
2) 发布人业务
任何一般用户在选择了一个或多个接收人后,都可以同时向他们发送同一件公文,发布人还可以查看甚至在必要时删除曾经发布过的公文。
3) 接收人业务
每一位接收人都可以及时看到发送给自己的公文,并可以在看完后删除该公文。如果一件公文是同时发送给多个用户的,其中一位接收人删除公文后,并不影响其他接收人查看此件公文。
3. 系统的设计
B/S 数据库模式采用三层结构:浏览器——Web服务器——数据库服务器,客户端除了浏览器组件外无需其它组件,所有的程序,数据库及其它组件都集中在服务器端,这样,所有的软件维护及数据库的备份都只需在服务器端进行。实质上,客户机与Web服务器之间类似于一种终端与主机的模式,而Web服务器与数据库服务器之间是一种Client/Server数据库模式。本系统使用IIS4.0作为Web服务器,使用MS SQL Server作为数据服务器。具体设计如图示:
本系统在MS SQL Server中创建了一个数据库,库中包含两个表:用户信息表和公文信息表。用户信息表包括用户名、口令、用户? 开身份、E-mail、电话等字段,其中用户名为关键字。公文信息表包括公文主题、内容、发布时间、发布人、发布人的IP以及以每个用户名作为字段名的一系列字段,其中以公文的主题和发布人作为关键字。
因为系统中每个用户都是通过浏览器使用系统的,为了系统的安全性和用户使用方便,我在用户信息表中使用了用户的公开身份字段,它的内容与用户名字段的内容是一一对应的。这样,每位用户在登陆系统时,是通过在浏览器中输入自己的用户名和口令来进入的,而发布人在选择接收人时,是通过查看用户的公开身份来选择用户,系统处理时则又是使用与用户的公开身份相对应的用户名来处理的。
因为系统中用户的数量是动态变化的,可以随时增加和减少,而每一件公文又都可能是发送给不同用户的,并且其中一位用户删除公文后还不能影响其他用户对该公文的操作。为了实现以上功能同时减少数据冗余,我使用了动态改变库结构的方法。具体如下:
1) 当超级用户增加、删除用户时,系统既相应地增加、删除用户信息表中的记录,又同时在公文信息表中增加、删除以用户名为字段名的字段(这些字段为Char型,可以为Null)。
2) 当发布人选择好接收人并发布公文时,首先查询用户信息表,将接收人的公开身份转化为用户名,然后在公文信息表中相应增加一条记录,记录下公文的主题、内容、发布时间、发布人、发布人的IP,同时将该条记录中以接收人用户名为字段的字段值置为“1”。
当发布人要查看、删除已发布的公文时,通过关键字来查看、删除相应的记录。
3) 当接收人要查看新公文时,系统将查询公文信息表中以接收人用户名为字段名的字段值为“1”的记录,按发布时间的倒序在接收人的浏览器中列出这些记录的公文主题字段的内容,这每一条主题是一个超级链接,接收人点击后即可浏览公文的内容。
当接收人欲删除浏览完的公文时,点击删除按钮,系统就将公文信息表中该条公文记录的以接收人用户名为字段名的字段值设置为“0”。这样处理就不会影响其他接收人接收该条公文了。而且每一条公文无论发送给几个接收人都只保存一条记录,大大节省了存储空间,提高了系统的效率。
4. 系统实现的关键技术
1) 在ASP中事务的处理以及增加、删除数据表中字段的实现。
如上所述,增加用户时需要对两个数据表(用户信息表、公文信息表)进行操作,如果有时系统刚刚在用户信息表中增加了一条记录,然而就在这一时刻,Web服务器的硬盘驱动器突然坏了,这时还没来得及在公文信息表中增加字段。这就会使事情变得很糟糕。在ASP中,我们可以使用Begin transaction和Commit transaction来定义事务块.在该块中显示的语句只有在执行Commit transaction后才发生效用。假如在到达该语句之前的任一点发生了错误,所有在该事务中的语句都不会发生效用。比如在下面的代码中,如果Web服务器的硬盘在执行完INSERT语句而在它的下一句之前发生了硬盘错误。没有数据会插入到用户信息表中。系统会倒转回执行Begin transaction之前的状态。
本系统主要使用ADO技术实现与数据库的连接。ADO的强大功能得益于Transact_SQL。在SQL Server中增加、删除一个数据表字段的Transact_SQL语法如下:
增加字段:alter table $#@60;数据表名称$#@62; add $#@60;字段名称 数据类型 Null/Not Null$#@62;
删除字段:alter table $#@60;数据表名称$#@62; drop column $#@60;数据表字段名称$#@62;[,…n]
在ASP中,我们可以通过ADO技术,借助Transact_SQL的功能,完成对数据库的各种操作。
本系统中使用ASP语言实现的增加用户部分的核心代码如下:
利用ADO访问数据库
set sn=server.createobject("adodb.connection")
sn.open "dsn=sql7; uid=rdy; pwd=ydr"
进行事务处理
begin transaction
在用户信息表中插入一条记录
sql="insert into yhxx(xm,kl,gksf,email,tel) values("&request.form("zhcyhm")&","&request.form("zhcmm")&","&request.form("zhshxm")&","&request.form("zhcem")&","&request.form("zhcdh")&")"
set rrs=sn.execute(sql)
在公文信息表中增加以用户名为字段名的字段
sql="alter table xxfbqx add " &request.form("zhcyhm")& " char(1) null"
set rrs=sn.execute(sql)
事务处理结束
commit transaction
2) 用ASP在下拉列表框中实现多项选择
系统要求发布人可以一次给多个接收人发送公文,于是,我在Html页面中插入了一个下拉列表框,框中列出的是备选的接收人。用户可以按住Ctrl键,并用鼠标选择多个接收人,然后点击“选定”按钮,完成接收人的选择。使用ASP语言具体实现的核心部分的代码如下:
$#@60;%sql="select * from yhxx"
set rrs=con.execute(sql)
已选择的接收人的人数
Dim intNumberSelected
由所有的选项连接而成的字符串,每两个选项之间以逗号分隔
Dim strSelectedTeams
由每一个选项作为一个元素形成的数组
Dim arrSelectedTeams
Dim I 循环变量
intNumberSelected = Request.QueryString("teams").Count
返回选项的个数
If intNumberSelected = 0 Then%$#@62;
$#@60;div align="center"$#@62;$#@60;center$#@62;$#@60;p$#@62;$#@60;select NAME="teams" MULTIPLESIZE="9"$#@62;
$#@60;%do while not rrs.eof 如果存放用户信息的表不为空%$#@62;
$#@60;option$#@62;$#@60;%response.write rrs("gksf") 将表中的用户公开身份字段的每条记录作为下拉列表框的一个选项显示出来%$#@62;$#@60;/option$#@62;
$#@60;%rrs.movenext
loop%$#@62; $#@60;/select$#@62; $#@60;br$#@62;
$#@60;input type="submit" value="选定"$#@62;
$#@60;input type="reset" value="重选" $#@62;$#@60;/p$#@62;
$#@60;/center$#@62;$#@60;/div$#@62;
$#@60;/form$#@62;
$#@60;%
Else
strSelectedTeams = Request.QueryString("teams")
arrSelectedTeams = Split(strSelectedTeams, ", ", -1, 1)%$#@62;
$#@60;p$#@62;您一共选择了$#@60;b$#@62;$#@60;%= intNumberSelected %$#@62;$#@60;/b$#@62;个接收人:$#@60;/p$#@62;
$#@60;p$#@62;$#@60;b$#@62;$#@60;%= strSelectedTeams 将所选项输出,每两项之间以逗号分隔%$#@62;$#@60;/b$#@62;$#@60;/p$#@62;
3) 怎样用ASP判断数据库中符合条件的记录是否存在
当使用recordset(记录集)对记录进行条件查询时,我们可以使用recordcount属性来统计有多少条符合条件的记录。而当我们使用connection(面向连接的对象)时,我们应怎么办呢?这种情况下的一个强有力的武器就是count()函数,这个函数的使用方法如下:
l 统计一个表中某一字段不为Null值的记录有多少条
例如:SELECT COUNT(name) FROM authors
这个例子计算表authors中名字字段中(name)不为Null值的记录的数目。如果相同的名字出现了不止一次,该名字将会被计算多次。
l 条件查询
例如:SELECT COUNT(name) FROM authors WHERE name=’Rdy’
这个例子返回名字为“Rdy”的记录的数目。如果这个名字在表authors中出现了两次,则此函数的返回值是2。
l 统计某一字段值互不相同的记录有几条
假如你想知道有不同名字的作者的数目。你可以通过使用关键字DISTINCT来得到该数目。例如:SELECT COUNT(DISTINCT name) FROM authors
如果名字“Rdy”出现了不止一次,它将只被计算一次。关键字DISTINCT 决定了只有互不相同的值才被计算。
须注意的是:当你使用COUNT(字段名)时,字段中的空值将被忽略。而使用count()时,没有指定任何字段,这个语句讲计算表中所有记录的数目,包括有空值的记录。
在本系统中我使用了第二种方法,代码如下:
$#@60;%sql="select count(xm) from yhxx where xm="& request("yhm")&""
con为一个connection对象
rs=con.execute(sql)
在用户信息表中查询姓名字段值等于用户输入的字符串的记录
if rs(0)=0 then%$#@62;
不存在这样的记录
$#@60;p$#@62;$#@60;tt$#@62;您输入的用户名不正确!$#@60;/tt$#@62;$#@60;/p$#@62;
$#@60;%else
存在这样的记录
……
end if%$#@62;
5. 结束语
B/S数据库模式由于其简单,使用维护方便将会成为数据库发展的必然趋势。运用ASP可完成单位内部网中的许多功能,如电子邮箱管理,BBS等。ASP结合ADO技术确实功能十分强大,速度快,效率高,占用内存少。但是,本系统要达到比较完美的阶段,尚需不断完善。