- Asp组件初级入门与精通系列之六 2004-08-04 online
- ASP中数据库调用时常见错误的现象和解决 2004-09-01 fogdragon
- 一些ASP程序中的数据库调用的错误 2006-02-15 ema100
- asp分页显示 2001-05-10 11830
- ASP错误处理 2002-11-18 jujishou
一、前言
提到ASP操作数据库,大多数人会想到:共用的连接字串ConStr、Conn.Open ConStr建立数据库连接、Conn.Execute SqlCmd方式执行命令、RecordSet.Open Sql,Conn,1,1取得记录集,的确这种方法被99%的人或公司采用。对于操作数据库过程中产生的错误,恐怕99%的人不会进行处理,要么在程序的开头加入on error resume next“轻松”跳过去、要么让错误信息连同错误代码一同“暴尸”在浏览者面前。对于前一种情况可能会产生让人莫明其妙的怪异结果,后一种情况,可能会在某个时间(比如连接数据库时)暴露您的敏感信息,影响网站安全。当然,还是有个别负责的程序员同志会在容易产生错误的操作后面加入if err.xxxx来处理可能的错误,但这似乎不是一个好办法,一不小心就可能漏掉了。
我至今也没有想明白,为什么在VB和ASP.NET中都存在的On Error Goto,偏偏在ASP中被取消了。
另外不得不提的是,当您在前面使用on error resume next而在后面不想resume next了,对不起,没办法,您只能把它“贯彻到底”。看看其它语言的异常机制,try..catch..finally随心所欲,真是爽酷了!
说了这么多,并不要为ASP引入诸如异常机制等新的内容,毕竟ASP语言本身也决定这是不可能实现的(ASP.NET中实现了),只是想在ASP中最普遍的也是最容易出现错误的数据库操作中,找到一种有效的错误处理方式,并把conn、RecordSet等封装起来,达到最大限度的精简。于是便有了下面的数据库类。
二、数据库类
1、功能
正如前面所说,这个类的目的是把ADODB.Connection、Adodb.Recordset等烦琐的操作封装起来并在类里实现错误处理。现在看看类的成员、属性和方法:
1)成员:(没有公有或保护成员)
2)属性:
ClassName-返回类名
Version-返回版本
LastError-返回最后的错误
IgnoreError-设置/返回是否忽略数据库错误
Connection-返回连接对象(ADODB.Connection)
ConnectionString-设置/返回连接字串(本示例为SQL Server,如为其它请根据实际设定)
FieldCount、PageSize、PageCount、AbsolutePage、AbsolutePosition、Bof、Eof-请参考Adodb.Recordset相应内容
3)方法:
Setup-设置连接数据服务器的帐号、密码、数据库名、主机/IP
Connect-连接数据库
Close-关闭数据库连接并释放资源
Query-执行数据库查询命令并返回数据集
ExeSQL-执行SQL命令(不返回数据库)
FieldName-返回指定序号的字段名
Fields-返回指定的(序号或字段名)字段的值
Data-同上
MoveNext、MovePrevious、MoveFirst、MoveLast-请参考Adodb.Recordset相应内容
2、实现代码(DBSql.inc.asp)
内容太长,点击此处打开/折叠... | |
<% '======================================================================== ' CLASS NAME: clsDB ' DESIGN BY : 彭国辉 ' DATE: 2003-12-18 ' SITE: http://kacarton.yeah.net/ ' Blog: http://blog.csdn.net/conch ' EMAIL: [email protected] ' MODIFY: ' 2004-6-25: 升级后的数据引擎,返回错误代号小于0(也可以是ASP对数值的 ' 定义有变),修改错误检测err.number>0 ==> err.number<>0 ' 2004-6-30:修改错误处理,忽略如游标类型改变等非错误性质的提示 ' '文章为作者原创,转载前请先与本人联系,转载请注明文章出处、保留作者信息,谢谢支持! '========================================================================
Class clsDB ' name of this class ' version of this class ' Error Object ' Connection Object ' RecordSet ' Connection string ' Database server host name or IP ' Database name ' Account to connection database ' Password to connection database ' get class name attribute. ' get class version attribute. ' Bof ' Class constructor, set class default attributes, you can change it ' Class destructor, free memory. End Class %> |
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=42869
不得不说,虽然看起来更多地语言采用“Try...Catch”,但“On Error”也不失为一种优秀的异常处理机制。
还有,对于你的代码,异常处理分布在每个过程里面,不如做一个通用的异常处理页面,理由如下:
1、你的过程内的异常处理只是简单地捕获异常并显示友好错误信息,在修复方面的工作做得不多,意义不大且工作重复;
2、用户似乎不应该看到过多的错误细节。
实现方法大概是,先On Error Resume Next,再在页面末尾用SSI(不推荐)、Server.Execute或者Server.Transfer转到错误信息处理页面,统一进行错误捕获和信息反馈。
我觉得,这个数据库类可能并不太实用,大概看起来就是把Recordset和Connection对象的常用成员组合到了一起……
——这些都只是我个人的一些粗浅认识而已,还请多批评指教。
对了,我觉得对于异常处理,我们可以把重点放在异常修复上。考虑考虑?
这种方法与其他人(包括以往的同事)交流时,大部分也表示不大习惯。这个类只是一个引子,后面的文章会用到它。
靳田说的大部分我同意,但这句话不赞同的, on error 这种语法已经被证明了是 vb 的一个令人生厌的弱项。 在 vb.net 里面使用了先进的 try.. catch... finally 机制也正说明了这一点。
On Error Goto MY_ERROR_HANDLER
'Try Start
... ...
'Try End
On Error Goto 0
goto GO_ON
MY_ERROR_HANDLER:
'Catch something
Select Case Err.Number
Case xxxxxx
... ...
Case Else
End Select
... ...
GO_ON:
'Finnaly
完全可以做到类似 Try Catch 的捕获。只不过不那么“优美”而已。
另外,
Dim lngErrorNumber as Long
On Error Resume Next
'Try Start
... ...
'Try End
lngErrorNumber = Err.Number
On Error Goto 0
Select Case lngErrorNumber
Case 0
...
Case xxx
'Handle
...
Case Else
...
End Select
这样的处理结构也不错——与前者相比,比较适合针对一两句代码设置陷阱。
对于开发人员而言,在什么地方设置陷阱,如何处理等等,是一种高级编程策略的体现。至于能力高低因人和经验而异,但没有和有之间的差别意义就不同了。
VB 有错误捕获和处理的能力,VB.Net 在这方面也许更强
个人认为这谈不上VB/VBS的弱项。
同感。
if err.number<>0 Then ShowError("数据库连接错误:(Server:" & m_strHost & ", Database:" & m_strDatabase & ")")
m_bIsConnect = true
这一句漏掉了 :Exit Sub(当然,针对ASP可以在ShowError中用 Response.End 来结束,但对于上面的代码而言,逻辑上不完整)
由此想到的题外话:诸如此类的代码,最好不要省事,写为
If .... Then
Else
End If
哪怕中间空着,但逻辑很清楚,也不容易出现人为失误——看你别的代码都有,就这一句漏掉了。
封装函数、类的时候,往往有很多种策略。谈不上究竟哪种好,哪种不好——关键看你选择哪一个 View 了。
比如,既然封装成为一个 Class,那么对于调用者来说,应该由它自己决定如何处理错误——我看到你的代码里有 LastError,那怎么不用上它呢?封装方法和函数的思路有很多种,各有各的好处。我个人比较喜欢类似 COM 的方法的封装:每一个方法都是 Bool 类型。如果返回值为 False,则调用者需要检查 LastErrorNumber(而不是LastErrorMessage,为什么?)
当然,你也可以约定你的调用者用别的方式来调用。比如无论如何都要检查某个 Bool 类型的 Property,或者抛出错误(异常)——Err.RaiseError(Estyle纠正我一下,不记得语法了,我在CoffeeBar)让调用者自行处理,呵呵
题外话,On Error Resume Next 在这一点上有一个很好的作用:消极容错。使用时应该根据逻辑适当分段,否则通篇用一两个 On Error Resume Next,那除非是为了“隐藏错误”,谈不上“错误处理”。
所以,在你的类中,ShowError() 这个方法就有点“越俎代疱”了。不妨采用类似于 IgnoreError 这样的思路,提供标准的、默认的错误处理方式之外,让调用者也可以设置一下错误处理的方式,甚至可以定制 ShowError() 的具体内容——比如 EStyle 说的 SSI、Transfer、Execute等方式。
说到这里,再想想,虽然封装这样一个类的实际意义未必很大,但通过它和你做的其它一些东西合起来提供一个开发框架,调用者只需要按照这个框架开发、定制一下内容,还是很有意义的。
何况,当你的这个开发框架比较成熟之后,可以用程序来生成它们——产生式编程?意义就更加重大了。
呵呵,以前有个同事做了一个软件来生成代码,但我个人不太喜欢他的开发框架和代码。后来自己摸索,但却没时间完成自动生成了。今天刚好见到有个RapidTier的作品,看起来不错,不过是.Net的。但我觉得在VBS这样的语言针对OOP提供“超能力”的领域来摸索这个事情似乎更有挑战性 ^oo^
<%
Rem =======================================数据库类=====================
Rem 定义类名称
Class jz_DbAccess
Rem ==================使用说明=========================================
Rem = 作用:集成了用数据库工作时使用的常见功能
Rem = 公有变量:Conn Connection对象
Rem = 公有变量:comm Command对象
Rem = 公有变量:param Parameter对象
Rem = 公有变量:rs Recordset对象
Rem = 属性: DbPath 定义Access数据库路径及名称,只写属性。
Rem = 属性: SqlDatabaseName 定义SQL数据库名称,只写属性。
Rem = 属性: SqlUsername 定义SQL数据库用户名称,只写属性。
Rem = 属性: SqlPassword 定义SQL数据库用户密码,只写属性。
Rem = 属性: SqlLocalName 定义SQL数据库服务器名称,只写属性。
Rem = 属性: TableName 定义表名称,只写属性。
Rem = 属性: MeterList 定义表的列名称列表,可加入top 等SQL 语句,只写属性。
Rem = 属性: SortField 定义表Order By排列方式,只写属性。
Rem = 属性: FilterField 定义表 where 过滤方式,只写属性。
Rem = 方法:DbSet(IsSqlDataBase,OpenComm,OpenRs) 定义用Access还是用Sql,并创建Connection对象,Command对象,Recordset对象
Rem = 方法:AddRecord(FieldList,ValueList) 把记录加到数据库里
Rem = 方法:EditRecord(FieldList,ValueList,Primary) 在数据库里更新已有的记录
Rem = 方法:DeleteRecord(Primary) 从数据库里删除记录
Rem = 函数:GetRecord() 在筛选和排序的基础上返回Recordset
Rem = 函数:GetRecords(Primary) 按参数返回记录
Rem = 方法:RsOpen(Sql,CursorType, LockType) 按参数打开游标
Rem = 函数: RsGetRows(Sql,CursorType, LockType) 将 Recordset 对象的多个记录恢复到数组中
Rem = 函数: RsGetString(sql,Cursor_Type, Lock_Type,StringFormat, NumRows, ColumnDelimiter, RowDelimiter, NullExpr)将 Recordset 作为字符串返回。
Rem =========================================================================================
Rem 定义私有变量
Private LocalDbPath,LocalSqlDatabaseName,LocalSqlUsername,LocalSqlPassword,LocalSqlLocalName
Rem 定义私有变量
Private LocalTableName,LocalSortField,LocalMeterList,LocalFilterField,LocalFen
Rem 定义公有变量
Public Conn,comm,param,rs,ConnStr
Rem 使用Initialize事件提供有缺省值的某些属性。
Private Sub Class_Initialize()
LocalFen="{$AddDate}"
End Sub
Rem 设置使用Terminate事件
Private Sub Class_Terminate()
Rem 内置函数 IsObject(expression) 确定表达式expression是否是一个自动对象。
Rem 为自动对象时,将对象变量 Rs 设置为 Nothing,从内存中完全删除,
if IsObject(rs) then set rs = nothing
Rem 为自动对象时,将对象变量 Comm 设置为 Nothing,从内存中完全删除,
if IsObject(comm) then set comm = nothing
Rem 为自动对象时,将对象变量 Conn 设置为 Nothing,从内存中完全删除,
if IsObject(Conn) then set Conn = nothing
End sub
Rem 因为方法是需外部访问的而且没有返回值,故被声明为公有过程
Public Sub close()
Rem 把私有变量LocalMeterList赋值为"*"
LocalMeterList="*"
Rem 把私有变量LocalMeterList赋值为Empty
LocalSortField=Empty
Rem 把私有变量LocalMeterList赋值为Empty
LocalFilterField=Empty
End Sub
Rem Property Let 过程设置属性值。
Public Property Let DbPath(vNewValue)
Rem 私有变量LocalDbPath赋值为属性值
LocalDbPath=vNewValue
End Property
Rem Property Let 过程设置属性值。
Public Property Let SqlDatabaseName(vNewValue)
Rem 私有变量LocalSqlDatabaseName赋值为属性值
LocalSqlDatabaseName=vNewValue
End Property
Rem Property Let 过程设置属性值。
Public Property Let SqlUsername(vNewValue)
Rem 私有变量LocalSqlUsername赋值为属性值
LocalSqlUsername=vNewValue
End Property
Rem Property Let 过程设置属性值。
Public Property Let SqlPassword(vNewValue)
Rem 私有变量LocalSqlPassword赋值为属性值
LocalSqlPassword=vNewValue
End Property
Rem Property Let 过程设置属性值。
Public Property Let SqlLocalName(vNewValue)
Rem 私有变量LocalSqlLocalName赋值为属性值
LocalSqlLocalName=vNewValue
End Property
Rem Property Let 过程设置属性值。
Public Property Let TableName(vNewValue)
Rem 私有变量LocalTableName赋值为属性值
LocalTableName=vNewValue
End Property
Rem Property Let 过程设置属性值。
Public Property Let MeterList(vNewValue)
Rem 私有变量LocalMeterList赋值为属性值
LocalMeterList=vNewValue
End Property
Rem Property Let 过程设置属性值。
Public Property Let SortField(vNewValue)
Rem 私有变量LocalSortField赋值为属性值
LocalSortField=" Order By "&vNewValue
End Property
Rem Property Let 过程设置属性值。
Public Property Let FilterField(vNewValue)
Rem 私有变量LocalFilterField赋值为属性值
LocalFilterField=" where "&vNewValue&" "
End Property
Rem Property Let 过程设置属性值。
Public Property Let Fen(vNewValue)
Rem 私有变量LocalFen赋值为属性值
LocalFen=vNewValue
End Property
Rem 因为方法是需外部访问的而且没有返回值,故被声明为公有过程
Public Sub DbSet(IsSqlDataBase)
Rem 判断参数IsSqlDataBase的值
If IsSqlDataBase = 1 Then
Rem 给公有变量 ConnStr 赋值
ConnStr = "Provider = Sqloledb; User ID = " & LocalSqlUsername & "; Password = " & LocalSqlPassword & "; Initial Catalog = " & LocalSqlDatabaseName & "; Data Source = " & LocalSqlLocalName & ";"
Else
Rem 给公有变量 ConnStr 赋值
ConnStr ="Provider = Microsoft.Jet.OLEDB.4.0;Data Source = " & Server.MapPath(LocalDbPath)
End If
End Sub
Rem 因为方法是不需外部访问的而且没有返回值,故被声明为私有过程
Private Sub Open_Obj(ObjType)
Select Case (ObjType)
Case ("Conn")
Rem 判断是否 不为自动对象时
If Not IsObject(Conn) then
Rem 语句 On Error 当一个错误发生时,这条语句就执行紧靠发生错误语句后面的语句,或者执行紧靠调用进程后面的语句。
On Error Resume Next
Rem 语句 Set 赋予一个变量或一个性质对象引用。当赋予的值为Nothing 时,使obectva 和任何以前指明的对象解除关系。
Set Conn = Server.CreateObject("ADODB.Connection")
Rem 使用连接属性打开数据库连接
conn.open ConnStr
Rem 判断是否发生错误
Rem 任何涉及 ADO 对象的操作都可能产生一个或多个提供者错误。产生错误时,可以将一个或多个 Error 对象置于 Connection 对象的 Errors 集合中。其他 ADO 操作产生错误时,将清空 Errors 集合,并且将新的 Error 对象置于 Errors 集合中
If Err Then
Rem 对 Errors 集合使用 Clear 方法,来删除集合中现有的全部 Error 对象。发生错误时,ADO 将自动清空 Errors 集合,并以基于新错误的 Error 对象填充集合。
err.Clear
Rem 语句 Set 赋予一个变量或一个性质对象引用。当赋予的值为Nothing 时,使obectva 和任何以前指明的对象解除关系。
Set Conn = Nothing
Rem 发送提示
Response.Write "数据库连接出错,请检查连接字串。"
Rem 停止
Response.End
End If
End If
Case ("Comm")
Rem 判断是否 不为自动对象时
if Not IsObject(comm) then
Rem 语句 Set 赋予一个变量或一个性质对象引用。当赋予的值为Nothing 时,使obectva 和任何以前指明的对象解除关系。
set comm=Server.Createobject("ADODB.Command")
Rem 指示指定的 Command 对象当前所属的 Connection 对象。
comm.ActiveConnection=conn
End if
Case ("Rs")
Rem 判断是否 不为自动对象时
If not IsObject(rs) Then set Rs = Server.CreateObject( "ADODB.Recordset" )
ENd Select
End Sub
Rem 因为方法是不需外部访问的而且有返回值,故被声明为私有函数
Private Function FieldListStr(FieldList,ValueList,format_type)
Rem 定义局部变量
Dim ChoppedFieldList,ChoppedValueList
Dim FieldValueList(2)
Dim FieldNum,ValueNum,i,post
Dim Field_str,Str_i,Value_str
Rem 把参数FieldList通过{$jz}断层分割转换为数组,赋值给局部变量ChoppedFieldList
Rem 内置函数 Split(expression[,delimiter[,count[,compare]]]) 把一个字符串分割并转换成数组。
ChoppedFieldList=Split(FieldList,LocalFen)
Rem 把参数ValueList通过{$jz}断层分割转换为数组,赋值给局部变量ChoppedValueList
Rem 内置函数 Split(expression[,delimiter[,count[,compare]]]) 把一个字符串分割并转换成数组。
ChoppedValueList=Split(ValueList,LocalFen)
Rem 把ChoppedFieldList的数组第一维的上边界,赋值给局部变量FieldNum
Rem 内置函数 UBound(arrayname[,dimension]) 返回数组某维的上边界。缺省维数时,为第一维。
FieldNum=UBound(ChoppedFieldList)
Rem 把ChoppedValueList的数组第一维的上边界,赋值给局部变量ValueNum
Rem 内置函数 UBound(arrayname[,dimension]) 返回数组某维的上边界。缺省维数时,为第一维。
ValueNum=UBound(ChoppedValueList)
Rem 判断 局部变量FieldNum与局部变量ValueNum是否相等,不等时,退出函数
if FieldNum<>ValueNum Then Exit Function
Rem 根据局部变量ValueNum,修改局部变量Value_str为二维数组
ReDim Value_str(3,ValueNum)
Rem 为局部变量Str_i赋初始量为0
Str_i=0
Rem 自定义私有过程 Open_Obj
Open_Obj "Conn"
Rem 打开一个将要增加记录的到表的连接
Set Rs = conn.Execute(LocalTableName,,2)
Rem 通过FieldNum进行循环
For i=0 to FieldNum
Rem 通过参数 format_type 给局部变量Field_str以不同的方式赋值
Select Case (format_type)
Case ("Add")
Rem 对局部变量Field_str进行字符串串联
Rem 自定义函数私有Str_add,以传入的三个参数进行字符串转换
Field_str=Str_add(Field_str,ChoppedFieldList(i),",")
Case ("Edit")
Rem 对局部变量Field_str进行字符串串联
Rem Str_add自定义私有函数,以传入的三个参数进行字符串转换
Field_str=Str_add(Field_str,ChoppedFieldList(i)&"=?",",")
ENd Select
Rem 局数变量数组Value_str第一维0赋值
Value_str(0,i)=ChoppedFieldList(i)
Rem 使用Recordset 对象含有由 Field 对象组成的 Fields 集合的Type属性可返回字段的基本特性,赋值给局数变量数组Value_str第一维1
Value_str(1,i)=Rs.Fields(ChoppedFieldList(i)).type
Rem 使用Recordset 对象含有由 Field 对象组成的 Fields 集合的DefinedSize 属性可返回已声明的字段大小,赋值给局数变量数组Value_str第一维2
Value_str(2,i)=rs.Fields(ChoppedFieldList(i)).DefinedSize
Rem 从局部变量数组ChoppedValueList中赋对应的值给赋值给局数变量数组Value_str第一维3
Value_str(3,i)=ChoppedValueList(i)
Next
Rem 使用 Close 方法可关闭 Connection 对象或 Recordset 对象以便释放所有关联的系统资源。
Rs.close
Rem 给局部变量数组FieldValueList赋值
FieldValueList(0)=Field_str
FieldValueList(1)=Value_str
FieldValueList(2)=FieldNum
Rem 局部变量数组FieldValueList的值赋给FieldListStr函数返回值
FieldListStr=FieldValueList
End Function
Rem 因为方法是不需外部访问的而且有返回值,故被声明为私有函数
Private Function Str_add(add_str,Str,char_str)
Rem 判断参数add_str是否为空值
if add_str="" then
Rem 为空时,函数返回值为参数Str
Str_add=str
else
Rem 不为空时,函数返回值为参数add_str&char_str&str
str_add=add_str&char_str&str
end if
End Function
Rem 因为方法是不需外部访问的而且没有返回值,故被声明为私有过程
Private Sub Param_cmd(str_0,str_1)
Rem 创建局部变量
dim i
Rem 通过参数Str_0循环
rem comm.Parameters.Refresh
for i=0 to str_0
Rem 用指定的属性创建新的 Parameter 对象
Rem Param 为公有变量
rem Response.Write(str_1(0,i)&"---"&str_1(1,i)&"---"&str_1(2,i)&"---"&str_1(3,i))
set param=comm.CreateParameter(str_1(0,i),str_1(1,i),&H0001,str_1(2,i),str_1(3,i))
Rem 使用 Append 方法将它们添加到 Parameters 集合
comm.Parameters.Append param
next
rem comm.Parameters.Refresh
End Sub
Rem 因为方法是不需外部访问的而且有返回值,故被声明为私有函数
Private Function str_addNum(Num,str,char_str)
Rem 创建局部变量
Dim i
Rem 通过参数Num循环
For i=0 to Num
Rem 循环进行字符串串联,并赋值给函数返回值
Rem 自定义私有函数Str_add,通过三个参数转换
str_addNum=Str_add(str_addNum,Str,char_str)
Next
End Function
Rem 因为方法是需外部访问的而且没有返回值,故被声明为公有过程
Public Sub AddRecord(FieldList,ValueList)
Rem 创建局部变量
Dim FieldValueList
Rem 判断私有变量LocalTableName是否为空
if (LocalTableName="") then
Rem 设置错误提示信息
Err.Raise vbobjectError+1,"DBAccess Server","TableName 未设置"
Rem 退出Sub 过程
Exit Sub
End if
Rem 通过自定义私有变量FieldListStr获取转换后的数组。
FieldValueList=FieldListStr(FieldList,ValueList,"Add")
Rem 判断FieldListStr是否为数组
If Not IsArray(FieldValueList) Then
Rem 退出Sub 过程
Exit Sub
Else
Rem 自定义私有过程 Open_Obj
Open_Obj "Conn"
Rem 自定义私有过程 Open_Obj
Open_Obj "Comm"
Rem 指示 Command 对象的类型为将 CommandText 作为命令或存储过程调用的文本化定义进行计算。
comm.CommandType=&H0001
Rem 使用 CommandText 属性定义命令(例如,SQL 语句)的可执行文本
comm.CommandText="Insert into "&LocalTableName&" ("&FieldValueList(0)&") values ("&str_addNum(FieldValueList(2),"?",",")&")"
rem Response.Write("Insert into "&LocalTableName&" ("&FieldValueList(0)&") values ("&str_addNum(FieldValueList(2),"?",",")&")")
Rem 调用自定义私有过程Param_cmd,添加到 Parameters 集合
Param_cmd FieldValueList(2),FieldValueList(1)
Rem 执行在对象的 CommandText 属性中指定的查询。如果 CommandText 属性指定按行返回查询,执行所产生的任何结果都将存储在新的 Recordset 对象中。如果该命令不是按行返回查询,则提供者返回关闭的 Recordset 对象。
comm.Execute
end if
End Sub
Rem 因为方法是需外部访问的而且没有返回值,故被声明为公有过程
Public Sub EditRecord(FieldList,ValueList,Primary)
Rem 创建局部变量
Dim FieldValueList
Rem 判断私有变量LocalTableName是否为空
if (LocalTableName="") then
Rem 设置错误提示信息
Err.Raise vbobjectError+1,"DBAccess Server","TableName 未设置"
Rem 退出Sub 过程
Exit Sub
End if
Rem 通过自定义私有变量FieldListStr获取转换后的数组。
FieldValueList=FieldListStr(FieldList,ValueList,"Edit")
Rem 判断FieldListStr是否为数组
If Not IsArray(FieldValueList) Then
Exit Sub
Else
Rem 自定义私有过程 Open_Obj
Open_Obj "Conn"
Rem 自定义私有过程 Open_Obj
Open_Obj "Comm"
Rem 指示 Command 对象的类型为将 CommandText 作为命令或存储过程调用的文本化定义进行计算。
comm.CommandType=&H0001
Rem 使用 CommandText 属性定义命令(例如,SQL 语句)的可执行文本
comm.CommandText="UpDate "&LocalTableName&" set "&FieldValueList(0)&" Where "&Primary
Rem 调用自定义私有过程Param_cmd,添加到 Parameters 集合
Param_cmd FieldValueList(2),FieldValueList(1)
Rem 执行在对象的 CommandText 属性中指定的查询。如果 CommandText 属性指定按行返回查询,执行所产生的任何结果都将存储在新的 Recordset 对象中。如果该命令不是按行返回查询,则提供者返回关闭的 Recordset 对象。
comm.Execute
end if
End Sub
Rem 因为方法是需外部访问的而且没有返回值,故被声明为公有过程
Public Sub DeleteRecord(Primary)
Rem 判断私有变量LocalTableName是否为空
if (LocalTableName="") then
Rem 设置错误提示信息
Err.Raise vbobjectError+1,"DBAccess Server","TableName 未设置"
Rem 退出Sub 过程
Exit Sub
End if
Rem 自定义私有过程 Open_Obj
Open_Obj "Conn"
Rem 执行 Sql 文本
conn.execute("Delete from "&LocalTableName&" where "&Primary)
End Sub
Rem 因为方法是需外部访问的而且有返回值,故被声明为公有函数
Public Function GetRecord()
Rem 判断私有变量LocalTableName是否为空
if (LocalTableName="") then
Rem 设置错误提示信息
Err.Raise vbobjectError+1,"DBAccess Server","TableName 未设置"
Rem 退出函数
Exit Function
End if
Rem 自定义私有过程 Open_Obj
Open_Obj "Conn"
Rem 设置涵数返回值为Recordset对象
set GetRecord=conn.execute("select "&LocalMeterList&" from "&LocalTableName&LocalFilterField&LocalSortField)
End Function
Rem 因为方法是需外部访问的而且有返回值,故被声明为公有函数
Public Function GetRecords(Primary)
Rem 自定义私有过程 Open_Obj
Open_Obj "Conn"
Rem 设置涵数返回值为Recordset对象,参数为Sql文本
set GetRecords=conn.execute(Primary)
End Function
Rem 因为方法是需外部访问的而且没有返回值,故被声明为公有过程
Public sub RsOpen(sql,Cursor_Type,Lock_Type)
Rem 自定义私有过程 Open_Obj
Open_Obj "Conn"
Rem 自定义私有过程 Open_Obj
Open_Obj "Rs"
Rem 打开游标
Rs.Open sql, Conn, Cursor_Type, Lock_Type,&H0001
End sub
Rem 因为方法是需外部访问的而且有返回值,故被声明为公有函数
Public Function RsGetRows(sql,Cursor_Type, Lock_Type,Rows)
Rem 自定义私有过程 Open_Obj
Open_Obj "Conn"
Rem 自定义私有过程 Open_Obj
Open_Obj "Rs"
Rem 打开游标
Rs.Open sql, Conn, Cursor_Type, Lock_Type,&H0001
Rem 当前记录位置是否位于 Recordset 对象的最后一个记录之后,为True时,将 Recordset 对象的多个记录恢复到数组中
if not rs.eof then RsGetRows=rs.GetRows(Rows)
Rem 使用 Close 方法可关闭 Connection 对象或 Recordset 对象以便释放所有关联的系统资源。
rs.close
End Function
Rem 因为方法是需外部访问的而且有返回值,故被声明为公有函数
Public Function RsGetString(sql,Cursor_Type, Lock_Type,StringFormat, NumRows, ColumnDelimiter, RowDelimiter, NullExpr)
Rem 自定义私有过程 Open_Obj
Open_Obj "Conn"
Rem 自定义私有过程 Open_Obj
Open_Obj "Rs"
Rem 打开游标
Rs.Open sql, Conn, Cursor_Type, Lock_Type,&H0001
Rem 当前记录位置是否位于 Recordset 对象的最后一个记录之后,为True时,将 Recordset 作为字符串返回。
if not rs.eof then RsGetString=rs.GetString(StringFormat, NumRows, ColumnDelimiter, RowDelimiter, NullExpr)
Rem 使用 Close 方法可关闭 Connection 对象或 Recordset 对象以便释放所有关联的系统资源。
rs.close
End Function
End Class
%>
3、使用示例
<%
Function HTMLEncode(str)
If IsNull(str) Then HTMLEncode = "(NULL)" _
Else HTMLEncode = Server.HTMLEncode(str)
End Function
Dim sql, i
Set sql = New clsDB
sql.Connect
sql.ExeSQL("update Customers set Address='中华人民共和国' where ID=1")
sql.Query("select * from Customers")
Response.Write "
" & Server.HTMLEncode(sql.FieldName(i)) & " | "" & HTMLEncode(sql.Data(i)) & " | " '此处可直接用字段名代替i
sql.Close
Set sql = Nothing
%>
三、小结
这还只是一个比较粗糙的数据库类,还有很多ADODB的特性没有添加在内,而且灵活性也不够。本文旨在为大家提供另一种思路,各位在看完本文后觉得还是有一点收获的话,我就很满足了。
此外,我的下一篇文章《将ASP查询分页封装起来》中将用到这个类。