- 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
- 浏览: 78121 次
- 来自: ...
-
文章分类
最新评论
-
leo_soul:
web应用中怎样在蜘蛛图里加入刻度呢?网上有一种加刻度的例子, ...
转载JfreeChart学习总结 -
星冰艳月:
没用DOCTYPE标签....
后果很严重
[分享]忙活了半天的纯CSS仿经典下拉菜单 -
PlayGod1984:
StandardLegend想知道这个类在那个包里
转载JfreeChart学习总结 -
抛出异常的爱:
主题: 转贴源代码 就是设计如果你这种方式写出文章应该就不 ...
转贴源代码就是设计 -
clamp:
对于没有受过专门训练的人来说,电路设计图、建筑设计图是看不懂的 ...
转贴源代码就是设计
一、前言
提到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: kacarton@sohu.com ' 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、使用示例
<!--#INCLUDE file="DBSql.inc.asp"-->
<%
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 "<table border=1><tr>"
For i=0 To sql.FieldCount-1
Response.Write "<td>" & Server.HTMLEncode(sql.FieldName(i)) & "</td>"
Next
Response.Write "</tr>"
While Not sql.Eof
For i=0 To sql.FieldCount-1
Response.Write "<td>" & HTMLEncode(sql.Data(i)) & "</td>" '此处可直接用字段名代替i
Next
Response.Write "</tr>"
sql.MoveNext
Wend
Response.Write "</table>"
sql.Close
Set sql = Nothing
%>
三、小结
这还只是一个比较粗糙的数据库类,还有很多ADODB的特性没有添加在内,而且灵活性也不够。本文旨在为大家提供另一种思路,各位在看完本文后觉得还是有一点收获的话,我就很满足了。
此外,我的下一篇文章《将ASP查询分页封装起来》中将用到这个类。
相关推荐
1、文件内容:ibus-table-chinese-erbi-1.4.6-3.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/ibus-table-chinese-erbi-1.4.6-3.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、更多资源/技术支持:公众号禅静编程坊
选择Java后台技术和MySQL数据库,在前台界面为提升用户体验,使用Jquery、Ajax、CSS等技术进行布局。 系统包括两类用户:学生、管理员。 学生用户只要实现了前台信息的查看,打开首页,查看网站介绍、自习室信息、在线留言、轮播图信息公告等,通过点击首页的菜单跳转到对应的功能页面菜单,包括网站首页、自习室信息、注册登录、个人中心、后台登录。 学生用户通过账户账号登录,登录后具有所有的操作权限,如果没有登录,不能在线预约。学生用户退出系统将注销个人的登录信息。 管理员通过后台的登录页面,选择管理员权限后进行登录,管理员的权限包括轮播公告管理、老师学生信息管理和信息审核管理,管理员管理后点击退出,注销登录信息。 管理员用户具有在线交流的管理,自习室信息管理、自习室预约管理。 在线交流是对前台用户留言内容进行管理,删除留言信息,查看留言信息。
面向基层就业个性化大学生服务平台(源码+数据库+论文+ppt)java开发springboot框架javaweb,可做计算机毕业设计或课程设计 【功能需求】 面向基层就业个性化大学生服务平台(源码+数据库+论文+ppt)java开发springboot框架javaweb,可做计算机毕业设计或课程设计 面向基层就业个性化大学生服务平台中的管理员角色主要负责了如下功能操作。 (1)职业分类管理功能需求:对职业进行划分分类管理等。 (2)用户管理功能需求:对用户信息进行维护管理等。 (3)职业信息管理功能需求:对职业信息进行发布等。 (4)问卷信息管理功能需求:可以发布学生的问卷调查操作。 (5)个性化测试管理功能需求:可以发布个性化测试试题。 (6)试题管理功能需求:对测试试题进行增删改查操作。 (7)社区交流管理功能需求:对用户的交流论坛信息进行维护管理。 面向基层就业个性化大学生服务平台中的用户角色主要负责了如下功能操作。 (1)注册登录功能需求:没有账号的用户,可以输入账号,密码,昵称,邮箱等信息进行注册操作,注册后可以输入账号和密码进行登录。 (2)职业信息功能需求:用户可以对职业信息进行查看。 (3)问卷信息功能需求:可以在线进行问卷调查答卷操作。 (4)社区交流功能需求:可以在线进行社区交流。 (5)个性化测试功能需求:可以在线进行个性化测试。 (6)公告资讯功能需求:可以查看浏览系统发布的公告资讯信息。 【环境需要】 1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境:IDEA,Eclipse,Myeclipse都可以。 3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可 4.数据库:MySql 5.7/8.0等版本均可; 【购买须知】 本源码项目经过严格的调试,项目已确保无误,可直接用于课程实训或毕业设计提交。里面都有配套的运行环境软件,讲解视频,部署视频教程,一应俱全,可以自己按照教程导入运行。附有论文参考,使学习者能够快速掌握系统设计和实现的核心技术。
三菱Fx3u程序:自动检测包装机电机控制模板,PLC脉冲与伺服定位,手自动切换功能,三菱Fx3u程序:自动检测包装机电机控制模板——涵盖伺服定位与手自动切换功能,三菱Fx3u程序,自动检测包装机。 该程序六个电机,plc本体脉冲控制3个轴,3个1pg控制。 程序内包括伺服定位,手自动切,功能快的使用,可作为模板程序,很适合新手。 ,三菱Fx3u程序; 自动检测包装机; 六个电机; PLC脉冲控制; 伺服定位; 手自动切换; 功能快捷键; 模板程序。,三菱Fx3u PLC控制下的自动包装机程序:六电机伺服定位与手自动切换模板程序
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
计及信息间隙决策与多能转换的综合能源系统优化调度模型:实现碳经济最大化与源荷不确定性考量,基于信息间隙决策与多能转换的综合能源系统优化调度模型:源荷不确定性下的高效碳经济调度策略,计及信息间隙决策及多能转的综合能源系统优化调度 本代码构建了含风电、光伏、光热发电系统、燃气轮机、燃气锅炉、电锅炉、储气、储电、储碳、碳捕集装置的综合能源系统优化调度模型,并考虑P2G装置与碳捕集装置联合运行,从而实现碳经济的最大化,最重要的是本文引入了信息间隙决策理论考虑了源荷的不确定性(本代码的重点)与店铺的47代码形成鲜明的对比,注意擦亮眼睛,认准原创,该代码非常适合修改创新,,提供相关的模型资料 ,计及信息间隙决策; 综合能源系统; 优化调度; 多能转换; 碳经济最大化; 风电; 光伏; 燃气轮机; 储气; 储电; 储碳; 碳捕集装置; P2G装置联合运行; 模型资料,综合能源系统优化调度模型:基于信息间隙决策和多能转换的原创方案
IPG QCW激光模块电源驱动电路设计与实现:包含安全回路、紧急放电回路及光纤互锁功能的多版本原理图解析,IPG QCW激光模块电源驱动电路设计与实现:含安全回路、紧急放电及光纤互锁等多重保护功能的原理图解析,IPG QCW激光模块电源驱动电路, 包含安全回路,紧急放电回路,光纤互锁回路等, 元件参数请根据实际设计适当调整,此电路仅供参考,不提供pcb文件 原理图提供PDF和KICAD两个版本。 ,IPG激光模块; QCW激光电源驱动; 安全回路; 紧急放电回路; 光纤互锁回路; 原理图PDF和KICAD版本。,IPG激光模块电源驱动电路图解:含安全与紧急放电回路
基于LSSVM的短期电力负荷预测模型及其性能评估:结果揭露精确度与误差分析,LSSVM在短期电力负荷预测中的结果分析:基于均方根误差、平均绝对误差及平均相对百分误差的评估。,LSSVM最小二乘支持向量机做短期电力负荷预测。 结果分析 均方根误差(RMSE):0.79172 平均绝对误差(MAE):0.4871 平均相对百分误差(MAPE):13.079% ,LSSVM(最小二乘支持向量机);短期电力负荷预测;均方根误差(RMSE);平均绝对误差(MAE);平均相对百分误差(MAPE),LSSVM在电力负荷短期预测中的应用及性能分析
1、文件内容:libmtp-examples-1.1.14-1.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/libmtp-examples-1.1.14-1.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、更多资源/技术支持:公众号禅静编程坊
资源内项目源码是均来自个人的课程设计、毕业设计或者具体项目,代码都测试ok,都是运行成功后才上传资源,答辩评审绝对信服的,拿来就能用。放心下载使用!源码、说明、论文、数据集一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 4、如有侵权请私信博主,感谢支持
2023-04-06-项目笔记-第四百一十六阶段-课前小分享_小分享1.坚持提交gitee 小分享2.作业中提交代码 小分享3.写代码注意代码风格 4.3.1变量的使用 4.4变量的作用域与生命周期 4.4.1局部变量的作用域 4.4.2全局变量的作用域 4.4.2.1全局变量的作用域_1 4.4.2.414局变量的作用域_414- 2025-02-21
MINIST数据集和春风机器学习框架
1、文件内容:ibus-table-chinese-wu-1.4.6-3.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/ibus-table-chinese-wu-1.4.6-3.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、更多资源/技术支持:公众号禅静编程坊
宿舍管理系统(源码+数据库+论文+ppt)java开发springboot框架javaweb,可做计算机毕业设计或课程设计 【功能需求】 系统拥有管理员和学生两个角色,主要具备系统首页、个人中心、学生管理、宿舍信息管理、宿舍分配管理、水电费管理、进入宿舍管理、出入宿舍管理、维修信息管理、卫生信息管理、考勤信息管理、留言板、交流论坛、系统管理等功能模块。 【环境需要】 1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境:IDEA,Eclipse,Myeclipse都可以。 3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可 4.数据库:MySql 5.7/8.0等版本均可; 【购买须知】 本源码项目经过严格的调试,项目已确保无误,可直接用于课程实训或毕业设计提交。里面都有配套的运行环境软件,讲解视频,部署视频教程,一应俱全,可以自己按照教程导入运行。附有论文参考,使学习者能够快速掌握系统设计和实现的核心技术。
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
人凤飞飞凤飞飞是粉色丰富
2024蓝桥杯嵌入式学习资料
image_download_1740129191509.jpg
基于Multisim仿真的带优先病房呼叫系统设计(仿真图) 设计一个病房呼叫系统。 功能 (1)当有病人紧急呼叫时,产生声,光提示,并显示病人的编号; (2)根据病人的病情设计优先级别,当有多人呼叫时,病情严重者优先; (3)医护人员处理完当前最高级别的呼叫后,系统按优先级别显示其他呼叫病人的病号。
基于STM32F103的3.6kW全桥逆变器资料:并网充电放电、智能切换与全方位保护方案,基于STM32F103的3.6kW全桥逆变器资料:并网充电放电、智能控制与全方位保护方案,逆变器光伏逆变器,3.6kw储能逆变器全套资料 STM32储能逆变器 BOOST 全桥 基于STM32F103设计,具有并网充电、放电;并网离网自动切;485通讯,在线升级;风扇智能控制,提供过流、过压、短路、过温等全方位保护。 基于arm的方案区别于dsp。 有PCB、原理图及代码ad文件。 ,逆变器; 储能逆变器; STM32F103; 3.6kw; 485通讯; 全方位保护; 智能控制; 方案区别; PCB文件; 原理图文件; ad文件。,基于STM32F103的3.6kw储能逆变器:全方位保护与智能控制