ASP对数据库的访问

写ASP程序时,一般情况总是使用的VBScript,不过也不只是这一种选择,也可以用JScript。但在用JScript作为ASP的语言时,比用VBScript有一些小小的不方便,比如RecordSet的GetRows方法。
在ASP中操作数据库,一般都要用到RecordSet对象,如果注重程序效率的话,可能就会用到RecordSet对象的GetRows方法,把记录集对象转换成数组,而操作数组在速度上将比用RecordSet对象的MoveNext方法快很多,而且可以在取出数组后尽早释放RecordSet对象,从而减少资源的占用,这也是优化ASP性能的一个方法。
在VBScript里,用RecordSet.GetRows方法取到的是一个二维数组,里面的数据可以通过遍历数组的方式来取得。
假设现在有一个数据库,其中有一个表名为mytable,有3个字段,名称分别为id,first,second。
复制代码 代码如下:’codebyxujiwei ‘
‘定义变量 Dimconn,rs,data,recN,i ‘连接数据库
Setconn=Server.CreateObject(“ADODB.Connection”)
conn.Open”Provider=Microsoft.Jet.OLEDB.4.0;DataSource=”&_
Server.MapPath(“data.mdb”) ‘获取记录集
Setrs=conn.Execute(“SELECTid,first,secondFROMmytable”) ‘获取数据数组
data=rs.GetRows() ‘关闭记录集,释放对象 rs.Close() Setrs=Nothing
‘获取记录数 recN=UBound(data,2) ‘循环输出数据 Fori=0TorecN
‘注意,数组下标从0开始 ‘显示数据库中数据
Response.Write(“ID:”&data(0,i)&”,First:”&data(1,i)&_
“,Second:”&data(2,i)&”br/”) Next ‘关闭数据库连接,释放对象 conn.Close()
Setconn=Nothing %
但是在JScript使用时,就会有一个问题,那就是JScript并没有二维数组,如果要用GetRows所获取的数据,必要将这个VBScript中的二维数组转换成JScript能识别的数组,即元素为数组的一个一维数组。
在JScript里,用GetRows方法获取的数组有一个toArray方法,可以转换成JScript中能用的数组,但是这个数组是一维的,也就是说,如果要像在VBScript一样使用的话,还需要我们自己来做转换。
查阅了MSDN及在网上搜索了相关的文章之后,我写了一个数组转换的函数用于在JScript中使用GetRows方法。
复制代码
代码如下:scriptlanguage=”JScript”runat=”server” //codebyxujiwei //
//定义变量 varconn,rs,vdata,data,recN,i; //连接数据库
conn=Server.CreateObject(“ADODB.Connection”);
conn.Open(“Provider=Microsoft.Jet.OLEDB.4.0;DataSource=”+
Server.MapPath(“data.mdb”)); //获取记录集
rs=conn.Execute(“SELECTid,first,secondFROMtest”);
//获取数据数组,并转换成为JScript中可用的数组类型
vdata=rs.GetRows().toArray(); //获取数据表的字段数 i=rs.Fields.Count;
//关闭记录集,释放对象 rs.Close(); rs=null; //转换数组
data=transArray(vdata,i); //获取记录数 recN=data.length; //循环输出数据
for(i=0;irecN;i++){ //注意,数组下标从0开始 //显示数据库中数据
Response.Write(“ID:”+data[i][0]+”,First:”+data[i][1]+
“,Second:”+data[i][2]+”br/”); } //关闭数据库连接,释放对象
conn.Close(); conn=null; //数组转换函数 //byxujiwei
//参数:arr-GetRows方法得到的对象用toArray方法得到的数组
//fieldslen-数据表字段数 functiontransArray(arr,fieldslen){
varlen=arr.length/fieldslen,data=[],sp; for(vari=0;ilen;i++){
data[i]=newArray(); sp=i*fieldslen; for(varj=0;jfieldslen;j++)
data[i][j]=arr[sp+j]; } returndata; } /script
对于一些更新频率不高,而使用次数比较多的数据,可以在成功获取数据数组之后,用Application对象来缓存起来,从而减少对数据库的查询次数,一定程序程度上优化ASP的性能。转地址:

  文/王汉洲

一般情况下,数据访问时间要比 ASP 代码解释,编译时间长,不要让数据检索成为影响 ASP 性能的瓶颈。 

  ASP即Active Server
Page,是微软推出的动态Web设计技术,是用于WWW服务的服务器端脚本环境,在站点的Web服务器上解释脚本,可产生并执行动态、交互式、高效率的站点服务器应用程序。

首先,讲一些老生常谈的话。比如:需要声明变量,要用 Response.Write SQL_string 来进行调试,要用 On Error Resume 
Next 来捕获错误。不要在 Application 和 Session 中存储 Connection 对象等等,都是一些很多人知道而又不屑一顾的常 
识。 

  概述

提高数据访问速度包含两方面内容:1 与数据库建立连接。2 检索数据。 

建立高效的连接是优化数据库访问的第一步。你需要了解连接池的概念( 参见文章: 连接池(Connection Pooling)介绍 );了解 
连接数据库的方法。另外,测试是很重要的,如果你想亲自进行测试,可以下载上一部分提到的 WAST ,它可以模拟大量用户同时 
点击的情况。在这里,假设你使用的数据库是 MS SQL Server 7.0 ,如果 操作系统是 NT ,那么你可以在性能监视器中监测 
SQL7 的用户连接数(counter:User Connections);如果操作系统是98的话,可以使用 SQL7 的 Profiler。 

  利用ASP,我们可以很容易地把HTML(超文本标记语言)文本、脚本命令及ActiveX组件混合在一起构成ASP页,以此来生成动态网页,创建交互式的Web站点,实现对Web数据库的访问。当用户使用浏览器请求ASP主页时,Web服务器响应,调用ASP引擎来执行ASP文件,并解释其中的脚本语言(JScript或VBScript),通过ODBC连接数据库,由数据库访问组件ADO(ActiveX
Data
Objects)完成数据库操作,最后ASP生成包含有数据查询结果的HTML主页返回用户端显示。

下面,开始讨论如何与数据库建立连接,以及连接池的问题。 

  由于ASP在服务器端运行,运行结果以HTML主页形式返回用户浏览器,用户在客户端浏览器看到的仅仅是ASP页的执行结果所生成的页,而ASP页本身的内容用户在客户端浏览器是看不到的,增加了系统的安全保密性。此外,ASP是面向对象的脚本环境,用户可自行增加ActiveX组件来扩充其功能,拓展应用范围。

1. 使用 OLEDB 

  ASP访问数据库步骤

与数据库建立连接有三种方法:DSN,DSN-less,OLEDB( 参见文章: 用ADO连接数据库的三种方法 )。建议使用 OLEDB。 

  在ASP中,可通过以下步骤实现对Web数据库的访问:

2. 尽快释放数据库对象 

  1、定义数据源

假设有 page1.asp 和 page2.asp,在多人同时点击的情况下,服务器可能会这样工作: 

  在Web服务器上打开“控制面板”,选中“ODBC”,在“系统DSN”下选“添加”,选定你希望的数据库种类、名称、位置等。本文定义“SQL
Server”,数据源为“HT”,数据库名称为“HTDATA”,脚本语言采用JScript。

第一个人:page1.asp 的1-5行, 
第二个人:page1.asp 的1-5行, 
第一个人:page1.asp 的6-20行, 
第二个人:page1.asp 的1-5行, 
第三个人:page1.asp 的1-5行, 
第四个人:page1.asp 的1-5行, 
第二个人:page1.asp 的6-20行, 
第一个人:page2.asp 的1-5行, 
…… 

  2、使用ADO组件查询Web数据库

设想一下:有几千人同时访问你的主页,那么,服务器就会执行数千行,数万行语句后才回到第一个人请求的页面上。因此,我们 
应尽可能快的处理某个功能,某个任务。看下列代码: 

  1)调用Server.CreateObject方法取得“ADODB.Connection”的实例,再使用Open方法打开数据库:

<% 
rs1.Open strSQL1,cnn1     ‘cnn1 is connection object 
rs2.Open strSQL2,cnn2 
rs3.Open strSQL3,cnn3 
…… 
‘处理 rs1 
‘处理 rs2 
‘处理 rs3 
…… 
rs1.Close 
rs2.Close 
rs3.Close 
cnn1.Close 
cnn2.Close 
cnn3.Close 
%> 

  conn = Server.CreateObject(“ADODB.Connection”)

这种处理结果集的方法会占用比你想象要多的资源,正确的用法应为: 

  conn.Open(“HT”)

<% 
rs1.Open strSQL1,cnn     ‘cnn is connection object 
‘处理 rs1 
rs1.Close 
cnn1.Close 
…… 
rs2.Open strSQL2,cnn 
‘处理 rs2 
rs2.Close 
cnn2.Close 
…… 
rs3.Open strSQL3,cnn 
‘处理 rs3 
rs3.Close 
cnn3.Close 

  2)指定要执行的SQL命令

…… 
%> 

  连接数据库后,可对数据库操作,如查询、修改、删除等,这些都是通过SQL指令来完成的,如要在数据表signaltab中查询代码中含有“X”的记录:

或许你会说:在 rs2 的处理中,我还需要 rs1 的值,所以不能在处理 rs2 前关闭 rs1。那么解决这个问题更好的办法是采用 
GetRows 和 GetString,在后面会有详细的说明。 

  sqlStr = “select * from signaltabswherescode like ‘%X%'”

尽快的释放对象是保证数据库连接重用的前提。( 参见文章: 让数据库的连接更有效 ) 

  rs = conn.Execute(sqlStr)

3. 创建 Connection 对象,充分利用连接池。 

  3)RecordSet的属性和方法

看下列代码: 

  为了更精确地跟踪数据,要用RecordSet组件创建包含数据的游标,游标就是储存在内存中的数据:

‘创建 Connection Object,打开 RecordSet 
Set cnn = Server.CreateObject(“ADODB.Connection”) 
cnn.Open strConnection 
Set rs = Server.CreateObject(“ADODB.RecordSet”) 
rs.Open strSQL,cnn 

  rs = Server.CreateObject(“ADODB.RecordSet”)

‘直接打开 RecordSet 
Set rs = Server.CreateObject(“ADODB.RecordSet”) 
rs.open strSQL,strConnection 

  rs.Open(sqlStr,conn,1,A)

在 asptoday 的 Enhancing Performance in ASP – Part 2 中对这两种方法进行了测试,结果表明直接打开 RecordSet 比创 
建 Connection 快23%(快在页面处理上,检索数据库的速度是一样的。)所以,这篇文章的结论是:When working with a 
single Recordset,pass the connection string into the ActiveConenction property. 

  注:A=1表示读取数据;A=3表示新增、修改或删除数据。

我对此有异议:快的代码不一定是好的代码。 

  在RecordSet组件中,常用的属性和方法有:

首先要说明的是,直接打开 RecordSet 的方法依然要创建与数据库的连接,只不过是由 ADO 自动完成的。其次,这个 
Connection 只有在该页面处理完后才能被释放(不管是 Recordset.Close 还是 Set recordset = Nothing 都不能做到释放该 
对象)。 

  rs.Fields.Count:RecordSet对象字段数。

Dim rs 
Dim strcnn 
strcnn = “Driver={SQL Server};Server=.;Database=pubs;UID=sa;PWD=;OLE DB Services=-1;” 
For i = 1 To 20 
  Set rs = Server.CreateObject(“ADODB.Recordset”) 
  rs.Open “SELECT * FROM Authors”,strcnn 
  rs.Close 
  Set rs = Nothing 
Next   

  rs(i).Name:第i个字段的名称,i为0至rs.Fields.Count-1

运行上面的代码,在性能监视器中你会发现数据库的连接被创建了20个! 

  rs(i):第i个字段的数据,i为0至rs.Fields.Count-1

Dim cnn,rs 
strcnn = “Driver={SQL Server};Server=.;Database=pubs;” &_ 
  ”UID=sa;PWD=;OLE DB Services=-1;” 
For i = 1 To 20 
  Set cnn = Server.CreateObject(“ADODB.Connection”) 
  cnn.Open strcnn 
  Set rs = Server.CreateObject(“ADODB.Recordset”) 
  rs.Open “SELECT * FROM Authors”,cnn 
  rs.Close 
  Set rs = Nothing 
  cnn.Close 
  Set cnn = Nothing 
Next 

  rs(“字段名”):指定字段的数据。

采用上面的代码,连接数只需要2个!(只为说明问题,不考虑速度) 

  rs.Record.Count:数据记录总数。

还有一点要说明的是:服务器处理 ASP 时不是一次只处理一个,也不是一次就把整个页面处理完,没有关闭的连接只会占用更多 
的资源。所以,尽快的释放 Connection ,使它回到连接池中才是良好的编程习惯。连接池是服务器共享的资源,它不属于某个 
ASP,也不属于某个 Session,或者某个 Application。 

  rs.EOF:是否最后一条记录。

WAST 是我常用的测试工具,但是测试是一种手段,代替不了实际。如果你对 WAST 的工作方式感兴趣,可以到它的主页去看看。 
 

  rs.MoveFirst:指向第一条记录。

4. 为多个 RecordSet创建一个 Connection 对象 

  rs.MoveLast:指向最后一条记录。

Dim cnn,rs1,rs2,r3 
strcnn = “Driver={SQL Server};Server=.;Database=pubs;UID=sa;PWD=;OLE DB Services=-1;” 
Set cnn = Server.CreateObject(“ADODB.Connection”) 
cnn.Open strcnn 
Set rs1 = Server.CreateObject(“ADODB.Recordset”) 
rs1.Open “SELECT * FROM Authors1”,cnn 
Set rs2 = Server.CreateObject(“ADODB.Recordset”) 
rs2.Open “SELECT * FROM Authors2”,cnn 
Set rs3 = Server.CreateObject(“ADODB.Recordset”) 
rs3.Open “SELECT * FROM Authors3”,cnn 
….. 

  rs.MovePrev:指向上一条记录。

道理很简单,这种做法不需要为每一个 RecordSet 创建一个连接,只要传递一个引用就够了。 

  rs.MoveNext:指向下一条记录。

5. 与多个数据库连接的问题。 

  rs.GetRows:将数据放入数组中。

在大部份应用中,我们只对一个数据库进行操作,但有时也会碰到与多个数据库连接的情况。下面我们讨论两种连接方式: 

  rs.Properties.Count:ADO的ResultSet或Connection的属性个数。

‘第一种:两个 Connection,两个 RecordSet。 
Set cnn1 = Server.CreateObject(“ADODB.Connection”) 
Set cnn2 = Server.CreateObject(“ADODB.Connection”) 
cnn1.Open “provider=sqloledb;data source=210.75.56.37;initial catalog=pubs;user 
id=coolbel;password=coolbel.com;” 
cnn2.Open “provider=sqloledb;data source=210.75.56.37;initial catalog=coolbel;user 
id=coolbel;password=coolbel.com;” 
Set rs1 = Server.CreateObject(“ADODB.RecordSet”) 
Set rs2 = Server.CreateObject(“ADODB.RecordSet”) 
rs1.Open “select * from authors”,cnn1 
rs2.Open “select * from mytable”,cnn2 
…… 

  rs.Properties(item).Name:ADO的ResultSet或Connection的名称。

‘第二种:一个 Connection,两个 RecordSet。 
Set cnn = Server.CreateObject(“ADODB.Connection”) 
cnn.Open “provider=sqloledb;data source=210.75.56.37;user id=coolbel;password=coolbel.com;” 
Set rs1 = Server.CreateObject(“ADODB.RecordSet”) 
Set rs2 = Server.CreateObject(“ADODB.RecordSet”) 
rs1.Open “select * from pubs..authors”,cnn 
rs2.Open “select * from coolbel..mytable”,cnn 
…… 

  rs.Properties:ADO的ResultSet或Connection的值。

第二种方法极不可取,不仅速度低,而且浪费资源。其效率低下的根本原因在于这种连接方式没有利用连接池,使得每一次请求都 
要重新创建与数据库的连接。 

  rs.close():关闭连接。

Click!测试第一种代码  Click!测试第二种代码  ( coolbel 不稳定,需要多测试几遍。) 

  4)关闭数据库

6. 对于 Disconnected RecordSet,不要忘记使 ActiveConnection = Nothing 

  conn.close()

  实例

  下面的实例是某技术中心商品查询系统中的Web功能模块开发,系统要求当用户输入查询信息,如:产地或产品类别后,系统能返回查询结果.我们以产品类别为例:catachoi.asp文件利用Form标签形成一个查询入口,当用户选择了某产品类别,并按下“Submit”按钮后,它将产品类别号以ProdName变量的形式送到p_result.asp中,p_result.asp根据ProdName的值,使用SQL语句在服务器端完成数据库表文件的查询,最后将查询结果送回浏览器端。

You can leave a response, or trackback from your own site.

Leave a Reply

网站地图xml地图