打印

[asp] asp快速开发方法之数据操作

这是我自己的心得,给大家作个参考。
我的目的是让开发变得简单,尽可能少地考虑实现语句,更多地把精力用于思考业务逻辑。希望我的文章对大家有所启发和帮助。
如果你对ASP不熟悉,可以先看以下教程:
1、http://布鲁斯狼的ASP编程入门进阶
2、www.w3schools.com的ASP教程(英文\中文),查看更多

好吧,让我们进入正题:
先看以下例子:
复制内容到剪贴板
代码:
<%
db_path = "database/cnbruce.mdb"
Set conn= Server.CreateObject("ADODB.Connection")
connstr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="&Server.MapPath(db_path)
conn.Open connstr
Set rs = Server.CreateObject ("ADODB.Recordset")
sql = "Select * from cnarticle"
rs.Open sql,conn,1,1
if rs.EOF and rs.BOF then
response.write ("暂时还没有文章")
else
Do Until rs.EOF
response.write("文章标题是:"& rs("cn_title"))
response.write("<br>文章作者是:"& rs("cn_author"))
response.write("<br>文章加入时间是:"& rs("cn_time"))
response.write("<br>文章内容是:"& rs("cn_content"))
response.write("<hr>")
rs.MoveNext
Loop
end if
rs.close
Set rs = Nothing
conn.close
set conn=Nothing
%>
嗯,这是一个典型的读取数据并显示的例子,参见:http://www.cnbruce.com/blog/showlog.asp?cat_id=26&log_id=448
嗯,确实简单。从上至下,很容易明白。但是当你对多个表进行读插删改的时候,当你的代码里有很多HTML\js混杂的时候,你会有疑问:为什么有这么多东西要重复呢?
所以一般我们把一些简单的操作独立出来,写成类或者函数放进包含文件(include)。

那么以上的操作我们可以使用两个文件来实现:
conn.asp
复制内容到剪贴板
代码:
<%
db_path = "database/cnbruce.mdb"
Set conn= Server.CreateObject("ADODB.Connection")
connstr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="&Server.MapPath(db_path)
conn.Open connstr
%>
showit.asp
复制内容到剪贴板
代码:
<!--#include file="conn.asp" -->
<%
Set rs = Server.CreateObject ("ADODB.Recordset")
sql = "Select * from cnarticle"
rs.Open sql,conn,1,1
if rs.EOF and rs.BOF then
response.write ("暂时还没有文章")
else
Do Until rs.EOF
response.write("文章标题是:"& rs("cn_title"))
response.write("<br>文章作者是:"& rs("cn_author"))
response.write("<br>文章加入时间是:"& rs("cn_time"))
response.write("<br>文章内容是:"& rs("cn_content"))
response.write("<hr>")
rs.MoveNext
Loop
end if
rs.close
Set rs = Nothing
conn.close
set conn=Nothing
%>
参考:http://www.cnbruce.com/blog/showlog.asp?cat_id=26&log_id=448

现在相对简单多了,如果有多个操作页面我们只要导入连接文件就可以了,不过还是不够简洁,哪里不简洁?
一直在创建server,一直在写close,这样很容易出错,并且看起来与内容无关的太多。

那我再改进下:
把conn.asp文件改成:
复制内容到剪贴板
代码:
<%
Dim Conn
Dim Rs
Sub CloseDatabase
    Conn.close
    Set Conn = Nothing
End Sub
Sub OpenDatabase
    Dim StrServer,StrUid,StrSaPwd,StrDbName
    StrServer="192.168.1.1"        '数据库服务器名
    StrUid="sa"            '您的登录帐号
    StrSaPwd=""            '您的登录密码
    StrDbName="cnbruce.mdb"        '您的数据库名称
        Set Conn = Server.CreateObject("ADODB.Connection")
        '用于连接ACCESS
        Conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & Server.MapPath(StrDbName)
        '用于连接MSSQL
        'Conn.ConnectionString = "Driver={sql server};driver={SQL server};server="&StrServer&";uid="&StrUid&";pwd="&StrSaPwd&";database="&StrDbName
        set rs=server.CreateObject("ADODB.RecordSet")
        conn.open
        if Err Then
            err.Clear
            Set Conn = Nothing
            GBL_CHK_TempStr = GBL_CHK_TempStr & "数据库连接错误!"
            Response.Write GBL_CHK_TempStr
            Response.End
        End If    
End Sub
%>
现在我们的showit.asp可以这样写:

showit.asp
复制内容到剪贴板
代码:
<!--#include file="conn.asp" -->
<%
sql = "Select * from cnarticle"
opendatabase
rs.Open sql,conn,1,1
If not Rs.eof then
    Do Until rs.EOF
    response.write("文章标题是:"& rs("cn_title"))
    response.write("<br>文章作者是:"& rs("cn_author"))
    response.write("<br>文章加入时间是:"& rs("cn_time"))
    response.write("<br>文章内容是:"& rs("cn_content"))
    response.write("<hr>")
    rs.MoveNext
    Loop
else
    response.write ("暂时还没有文章")
end if
Closedatabase
%>
嗯,我们又少写了一些东西,这样是最简单的吗?当然不是!还可以更简单。
使用GetRows把查询出来的数据传给一个变量,使用ubound方法取得数据记录条数。
不明白?没关系,让我们继续往下看:

再建个文件:sql.asp

sql.asp
复制内容到剪贴板
代码:
<%
Class DataTable
    public Function SelectData(sql)
        If sql<>"" then
            opendatabase
            Rs.open sql,conn,1,1
            If not Rs.eof then
                Thedata=Rs.GetRows(-1)
                Closedatabase
            Else
                Closedatabase
            End If
        End If
        SelectData=Thedata
    End Function
End Class
%>
嗯,复制它就可以了,现在我们的showit.asp可以简单地这样写:

showit.asp
复制内容到剪贴板
代码:
<!--#include file="conn.asp" -->
<!--#include file="sql.asp" -->
<%
sql = "Select * from cnarticle"
set loadData=new DataTable
Thedata=loadData.SelectData(sql)
If isarray(Thedata) then
    Num=ubound(Thedata,2)
    for i=0 to Num
        response.write("文章标题是:"& Thedata(1,i))
        response.write("<br>文章作者是:"& Thedata(2,i))
        response.write("<br>文章加入时间是:"& Thedata(3,i))
        response.write("<br>文章内容是:"& Thedata(4,i))
        response.write("<hr>")
    next
else
    response.write("暂时还没有文章")
End If
%>
呵呵,这样,我们只要用两句语句就完成了数据的读取。同样的,通过在sql.asp中加入
复制内容到剪贴板
代码:
<%
    public Function SelectDataNum(sql)
        If sql<>"" then
            Opendatabase
            Rs.open sql,conn,1,1
            If not Rs.eof then
                Thedata=Rs.GetRows(-1)
                Closedatabase
                Num=ubound(Thedata,2)
            Else
                Closedatabase
            End If
        End If
        SelectDataNum=Num
    End Function
%>
我们就可以使用
复制内容到剪贴板
代码:
<%
sql = "Select * from cnarticle"
set loadData=new DataTable
Num=loadData.SelectDataNum(sql)
%>
来取得记录条数,可以用于分页或者用户名是否重复的判断。

其它的对数据记录的操作我们新建一个类,使用UpdateTable来完成操作:
复制内容到剪贴板
代码:
<%
Class DataTable
    public Function UpdataSql(sql)
        If sql<>"" then
            Opendatabase
            conn.execute(sql)
            Closedatabase
        End If
    End Function
End Class
%>
复制内容到剪贴板
代码:
<%
sql = "delete from cnarticle"
set UpdateDate=new DataTable
UpdateDate.UpdataSql(sql)
%>
当然你也这以这样写:
复制内容到剪贴板
代码:
<%
sql="insert into cnarticle(cn_title,cn_author,cn_content) values(' "&whattitle&" ',' "&whoauthor&" ',' "&whatcontent&" ')"
opendatabase
conn.execute(sql)
closedatabase
%>
考虑到可能删除语句我们会这么写:
sql="delect from cnarticle where id in(1,3,5,6,7,8)"

我新建一个类DeldataTable,直接使用DeldataTable.DeldataSql(tableName,DelField,id)完成记录的删除操作。
复制内容到剪贴板
代码:
<%
Class DataTable
    dim tempvalue
    public Function DeldataSql(tableName,DelField,id)
        If tableName<>"" and id<>"" then
            sql="delete from "&tableName
            If isnumeric(id) and instr(id,",")=0 then
                sql = sql & " where "&DelField&" = "&id
            Else
                sql = sql & " where "&DelField&" in ("& id &")"
            End If
            Opendatabase
                conn.execute(sql)
            Closedatabase
            tempvalue=true
        Else
            tempvalue=false
        End If
        DeldataSql=tempvalue
    End Function
End Class
%>
以下是我的sql.asp文件,请自己进行增删
复制内容到剪贴板
代码:
<%
'用于查询数据
Class DataTable
    '查出记录
    public Function SelectData(sql)
        If sql<>"" then
            opendatabase
            Rs.open sql,conn,1,1
            If not Rs.eof then
                Thedata=Rs.GetRows(-1)
                Closedatabase
            Else
                Closedatabase
            End If
        End If
        SelectData=Thedata
    End Function
    '查出记录条数
    public Function SelectDataNum(sql)
        If sql<>"" then
            Opendatabase
            Rs.open sql,conn,1,1
            If not Rs.eof then
                Thedata=Rs.GetRows(-1)
                Closedatabase
                Num=ubound(Thedata,2)
            Else
                Closedatabase
            End If
        End If
        SelectDataNum=Num
    End Function
    '使用select count(*) from tablename 查出记录有数
    public Function SelectCountNum(sql)
        If sql<>"" then
            Opendatabase
            Rs.open sql,conn,1,1
            If not Rs.eof then
                Thedata=Rs.GetRows(-1)
                Closedatabase
                Num=Thedata(0,0)
            Else
                Closedatabase
            End If
        End If
        SelectCountNum=Num
    End Function
    '将查询的数据全部生成隐藏值
    public Function GetHiddenData(sql)
        dim tempvalue
        If sql<>"" then
            Opendatabase
            Rs.open sql,conn,1,1
            If not Rs.eof then
                Thedata=Rs.getRows(-1)
                TheFieldCount=rs.fields.count
                For i=0 to TheFieldCount-1
                    TheFieldList = TheFieldList & Rs.fields(i).name & ","
                Next
                Closedatabase
                TheField = split(TheFieldList,",")
                For i=0 to TheFieldCount-1
                    tempvalue = tempvalue & "<input type=""hidden"" id="""&TheField(i)&""" name="""&TheField(i)&""" value="""&Thedata(i,0)&""" />"
                Next
            Else
                Closedatabase
            End If
        End If
        GetHiddenData=tempvalue
    End Function
    public Function UpdataSql(sql)
        If sql<>"" then
            Opendatabase
            conn.execute(sql)
            Closedatabase
        End If
    End Function
    
    public Function DeldataSql(tableName,DelField,id)
        dim tempvalue
        If tableName<>"" and id<>"" then
            sql="delete from "&tableName
            If isnumeric(id) and instr(id,",")=0 then
                sql = sql & " where "&DelField&" = "&id
            Else
                sql = sql & " where "&DelField&" in ("& id &")"
            End If
            Opendatabase
                conn.execute(sql)
            Closedatabase
            tempvalue=true
        Else
            tempvalue=false
        End If
        DeldataSql=tempvalue
    End Function
End Class
%>
个人见解,有疑问或者有更好方法的请跟贴。
转载请注明作者及出处。作者:wowhhz

[ 本帖最后由 wowhhz 于 2007-8-7 13:40 编辑 ]
本帖最近评分记录
  • 5do8 威望 +3 总结的不错,对初学者很有用。 2007-8-6 12:24
不管多累,我还得坚持
赶上直播了
修行的魔法师
不错~~
从楼主的代码可以看出,楼主对封装的理解还不够。精神可嘉

TOP

还在为头像烦恼?还在为不能关注好友动态烦忧?快来蓝色理想家园吧!
还请CJJ告诉我应该怎么做更好呢
不管多累,我还得坚持

TOP

一条DELETE一个类,一条UPDATE一个类,很有意义么?

这是我以前常用的一个数据操作的类,不过现在看来,问题还是很多,是一个不成熟的东西。
复制内容到剪贴板
代码:
<%
'----******************** TConnString *****************************----
'数据库连接字符串结构体
Class TConnString
    Public DBName,DBPath,DBServer,DBUser,DBPass
End Class
'----******************** TConnString *****************************----
'----********************* TDBOperate *****************************----
'通用数据库操作类
'Version: v0.2
Class TDBOperate
    Private cls_oConn,cls_oRS '类私有Connection对象、RecordSet对象
    Private cls_sErrInfo,cls_sConn,cls_sSQL,cls_sURL,cls_sFormAction
    Private cls_iPageSize, cls_iDBType '分页数, 数据库类型
    Private cls_bUseOpen
    '*****************************************
    ' 类型:只写属性
    ' 目的:设置数据库的类型
    ' 参数:a_iDBType:数据库类型
    ' 返回:无
    ' 作者:cjj
    ' 时间:2006-6-14
    ' 版本:v1.0
    '*****************************************
    Public Property Let DBType(a_iDBType)
        cls_iDBType = a_iDBType
    End Property
    '*****************************************
    ' 类型:    只读属性
    ' 目的:    获取数据库的类型
    ' 参数:    无
    ' 返回:    数据库的类型常量
    ' 作者:cjj
    ' 时间:2006-6-14
    ' 版本:v1.0
    '*****************************************
    Public Property Get DBType()
        DBType = cls_iDBType
    End Property
    '*****************************************
    ' 类型:    属性
    ' 目的:    根据获取的Connection String,创建数据库连接
    ' 参数:    a_sConn:数据类型字符串
    ' 返回:    无
    ' 作者:cjj
    ' 时间:2006-6-14
    ' 版本:v1.0
    '*****************************************
    Public Property Let setConn(a_sConn)
        Dim sObjType
        sObjType = LCase(TypeName(a_sConn))
        If sObjType <> "string" Then
            cls_sErrInfo = cls_sErrInfo & "<li>SetConn:非法的字符串参数</li>" & Chr(10)
            Exit Property
        End If
        Set cls_oConn = CreateObject("Adodb.Connection")
'        On Error Resume Next
        cls_oConn.Open a_sConn

        If Err Then
            Err.Clear
            Set cls_oConn = Nothing
            cls_sErrInfo = cls_sErrInfo & "<li>数据库连接出错</li>" & Chr(10)
        End If
'          On Error Goto 0
    End Property
    '*****************************************
    ' 类型:属性
    ' 目的:根据获取的Connection对象,创建数据库连接
    ' 参数:a_oConn:数据类型字符串
    ' 返回:无
    ' 作者:cjj
    ' 时间:2006-6-14
    ' 版本:v1.0
    '*****************************************
    Public Property Set setConn(ByVal a_oConn)
        Dim sObjType,sConn
        Dim oConnStr
        sObjType = LCase(TypeName(a_oConn))
        Select Case sObjType
        Case "connection"
            '设置Connection对象
            Set cls_oConn = a_oConn
        Case "tconnstring"
            sConn = ""
            Set oConnStr = a_oConn
            Select Case (cls_iDBType)
            Case gbl_iDB_Access
                sConn = "Provider = microsoft.jet.oledb.4.0; User ID = " & oConnStr.DBUser & "; Password = " & Replace(oConnStr.DBPass, Chr(0), "") & ";" & "Data Source = " & Server.Mappath(oConnStr.DBPath & oConnStr.DBName) & ";"
            Case gbl_iDB_MsSQL
                sConn = "Provider = Sqloledb; User ID = " & oConnStr.DBUser & "; Password = " & Replace(oConnStr.DBPass, Chr(0), "") & ";Initial Catalog = " & oConnStr.DBName & "; Data Source = " & oConnStr.DBServer & ";"
            End Select
            If sConn = "" Then
                cls_sErrInfo = cls_sErrInfo & "<li>数据库连接对象出错,无法创建Connection对象</li>" & Chr(10)
                Exit Property
            End If
            '设置Connection连接串值,供ConnStr属性返回
            cls_sConn = sConn
            Set cls_oConn = CreateObject("Adodb.Connection")
'            On Error Resume Next
            cls_oConn.Open(sConn)

            If Err Then
                Err.Clear
                Set cls_oConn = Nothing
                cls_sErrInfo = cls_sErrInfo & "<li>数据库连接出错</li>" & Chr(10)
            End If
'              On Error Goto 0
        Case Else
            cls_sErrInfo = cls_sErrInfo & "<li>SetConn:非法的对象参数</li>" & Chr(10)
            Exit Property
        End Select
    End Property
      '*****************************************
      ' 类型:属性
      ' 目的:设置RecordSet对象
      ' 参数:a_oRS:   RecordSet对象
      ' 返回:无。
      ' 作者:cjj
      ' 时间:2006-6-14
      ' 版本:v1.0
      '*****************************************
      Public Property Set SetRS(a_oRS)
          If LCase(TypeName(a_oRS))<>"recordset" Then
              cls_sErrInfo = cls_sErrInfo & "<li>非法的RecordSet对象</li>" & Chr(10)
              Exit Property
          End If
          '设置RecordSet对象
          Set cls_oRS = a_oRS
      End Property
      '*****************************************
      ' 类型:属性
      ' 目的:设置RecordSet对象
      ' 参数: a_oRS:   RecordSet对象
      ' 返回:返回一RecordSet对象
      ' 作者:cjj
      ' 时间:2006-6-14
      ' 版本:v1.0
      '*****************************************
      Public Property Get getRS()
          Set GetRS = cls_oRS
      End Property
      '获取Connection对象
      Public Property Get getConn()
          If cls_sErrInfo <> "" Then
              Call ShowErrors()
          End If
          If LCase(TypeName(cls_oConn))<>"connection" Then
              cls_sErrInfo = cls_sErrInfo & "<li>Connection对象获取失败</li>"
              Exit Property
          End If
          Set GetConn = cls_oConn
      End Property
      '返回数据库连接字符串
      Public Property Get ConnStr
          ConnStr = cls_sConn
      End Property
    '分页
    Public Property Let PageSize(ByVal a_iPageSize)
        cls_iPageSize = a_iPageSize
    End Property
    '是否采用Open方法创建记录集
    Public Property Let isUseOpen(ByVal a_bOpen)
        cls_bUseOpen = a_bOpen
    End Property
      '执行数据操作
      Public Function Execute(ByVal a_sSQL)
          Dim sSQL
          If Len(cls_sErrInfo)>0 Then
              Call ShowErrors()
'              Exit Function
          End If
          sSQL = Trim(a_sSQL)
          If (sSQL = "" oR isEmpty(sSQL) oR isNull(sSQL)) Then
              Exit Function
          End If
          If TypeName(cls_oConn)="Connection" Then
'On Error Resume Next
Response.Write("SQL:" & sSQL & "<br/>")
              If (cls_bUseOpen Or (cls_iPageSize>0)) Then
                  Set cls_oRS =  CreateObject("Adodb.RecordSet")
                  If (cls_iPageSize>0) Then
                      cls_oRS.PageSize = cls_iPageSize
                      cls_oRS.Open sSQL,cls_oConn,1,1
                  Else
                      cls_oRS.Open sSQL,cls_oConn,0, 1
                  End If
              Else
                  Set cls_oRS = cls_oConn.Execute(sSQL)
              End If
              If Err Then
'Response.Write("sql:" & sSQL & "<br />")
'Response.End()
'                  Set cls_oRS=Nothing
              End If
              On Error Goto 0
          Else
              cls_sErrInfo = cls_sErrInfo & "<li>非法的Connection对象</li>" & Chr(10)
              Call ShowErrors()
          End If
          Set Execute = cls_oRS
      End Function
      '执行存储过程
      Public Function ExecuteSP(ByVal a_sProc, ByVal a_sParas)
          Dim sProc : sProc=Trim(a_sProc)
          Dim sParas : sParas = a_sParas
          Dim oCmd
          Set ExecuteSP=nothing
          If IsNone(sProc) Then
              Exit Function
          End If
          If Len(cls_sErrInfo)>0 Then
              Call ShowErrors()
'              Exit Function
          End If
          If LCase(TypeName(cls_oConn))="connection" Then
              If Not IsNone(sParas) Then
'Response.Write("EXECUTE " & sProc & " " & sParas)
'Response.End
                  Set cls_oRS =  cls_oConn.Execute("EXECUTE " & sProc & " " & sParas)                  
              Else
                  Set cls_oRS = cls_oConn.Execute("EXECUTE " & sProc)
              End If
          Else
              cls_sErrInfo = cls_sErrInfo & "<li>非法的Connection对象</li>" & Chr(10)
              Call ShowErrors()
          End If
          Set ExecuteSP = cls_oRS
      End Function
        '*****************************************
        ' 类型:过程
        ' 目的:显示分页类中出现的错误信息
        ' 参数:无
        ' 返回:无
        ' 作者:cjj
        ' 时间:2006-6-14
        ' 版本:v1.0
        '*****************************************
      Private Sub ShowErrors()
          If Len(cls_sErrInfo)>0 Then
              cls_sErrInfo = "<ul>" & Chr(10) & cls_sErrInfo & "</ul>" & Chr(10)
              Response.Write(cls_sErrInfo)
              Response.End
          End If
      End Sub
       '初始化
      Private Sub Class_Initialize()
          '设置默认数据库为access
          cls_iDBType = gbl_iDB_Access
          '默认不使用Open方法建立记录集
          cls_bUseOpen = false
          '分页大小
          cls_iPageSize = 0
      End Sub
      '类销毁
      Private Sub Class_Terminate()
          If LCase(TypeName(cls_oConn))<>"nothing" Then
              cls_oConn.Close
              Set cls_oConn = Nothing
          End If
          If LCase(TypeName(cls_oRS))<>"nothing" Then
       '       cls_oRS.Close
              Set cls_oRS = Nothing
          End If
      End Sub
  End Class
  '----********************* TDBOperate *****************************----
%>
[ 本帖最后由 cjj 于 2007-8-4 12:46 编辑 ]

TOP

好像有点不必要,写成方法,好像更好些吧!!?

TOP

嗯,事实上确实没必要用类,只是想让它分开清晰点,去掉那个类名同样可以使用,而且能更简洁

那个deleteTable确实可以没有的,Update那个完全够用了
只是懒,对类似经典论坛里短消息作删除操作,我就没必要再写其它语句,直接拿这个函数就可以了,连SQL语句都免了,呵呵~

cjj那个考虑的因素更多,值得借鉴

[ 本帖最后由 wowhhz 于 2007-8-4 13:24 编辑 ]
不管多累,我还得坚持

TOP

看了两位的代码,面向对象程序设计偶要再看一遍

TOP

事实上这个只是把平常使用中的常用语句独立出来做成方法,希望由此提高工作效率,我们经常为别人简化操作,我不知道大家有没有什么好的方法用来简化自己的工作呢?我一直以为学计算机的目的就是把事情简单化,而不单是提升性能;沟通交流的目的是为了让事情更好更快地朝着目标发展,而不是每个人都去发明同一种轮子。
如何去做呢,还得大家多多把好的思路贴上来,有可能一个想法很快就能成为现实。
不管多累,我还得坚持

TOP

写代码的人追求什么?简洁的代码,完成功能。一个程序的好坏,我们主要看性能、安全性、可扩展性、可移植性。我不提代码的可读性,是因为性能好的代码,可读性必然是差的。

可惜我们现在看一个程序的好坏,主要就看功能。可是作为编程的人,不怕实现不了,就怕想不到......

封装时,我们提供简单的方法来实现复杂的功能,我们封装不变的部分,不封装变化很多的部分。拿楼主的例子,SELECT语句,不同的数据库有不同的支持。我们既然对SQL做封装,我们就应该考虑的不同的数据库支持的SQL有所不同。

封装时我们就该考虑到这种情况,我们的封装的扩展上就该考虑到这些东西。不是简单的一个CLASS,几个FUNCTION、SUB之类的就可以了。我们在封装,有些只要几行代码就能实现的功能,有必要多加N行来实现个实现,只是为了方便调用?

[ 本帖最后由 cjj 于 2007-8-5 12:30 编辑 ]

TOP

嗯,你说的对,为了代码简单好用,首先封装起来的代码应该健壮(性能\容错\可移植等)。我也写过程序,明白性能对程序的重要性。
其次,即然讲的是方法,只要能达到目的,用怎么样的表现形式确实不重要。

除了上面那个删除类,是出于方便自己放在那的。我有考虑过不同数据库对SQL语句的支持是不同的,所以我没有生成SQL来执行,而是由使用者来定义SQL语句,并把SQL语句作为参数进行调用,返回结果,所以并没有封装SQL语句,排除掉不确定的因素,这样可移植性就增强了,达到了简化的目的。

[ 本帖最后由 wowhhz 于 2007-8-5 14:48 编辑 ]
不管多累,我还得坚持

TOP

哦,详细看看

TOP

上面的SELCT语句类,没看清楚,不好意思。

编程时,为了达到目的,我们需要选择最佳的手段。而不是为达目的,不择手段。

对同一问题,我们使用不同的方法来解决,就是为了找出在各种环境下最佳的解决方法。

TOP

用类 比较好 符合工程思想
t9

TOP

之前做过一些测试,使用
复制内容到剪贴板
代码:
if rs.EOF and rs.BOF then
response.write ("暂时还没有文章")
else
Do Until rs.EOF
......
rs.MoveNext
Loop
end if
这种,边读记录边显示的方式虽然使用的普遍性很高,代码也易读,但是性能上没有使用GetRows列出记录的效率高,所以使用MoveNext来移动记录的方法我没有采用。使用GetRows之后,字段不能再用rs("xxx")这种方式,只能使用传递的二维变量数组进行排列,这个就是这种方法的限制,但是不要紧,我们在查询的SQL语句中字段用*号的,它按照表中字段的顺序排列,不然就按照SQL语句中字段的顺序排列
复制内容到剪贴板
代码:
sql = "Select * from cnarticle"
'如果SQL中字段为*那么表中顺序应该是“作者,标题,时间,内容”,不然就按SQL中字段顺序来排列
......
for i=0 to Num
        response.write("文章标题是:"& Thedata(1,i))
        response.write("<br>文章作者是:"& Thedata(2,i))
        response.write("<br>文章加入时间是:"& Thedata(3,i))
        response.write("<br>文章内容是:"& Thedata(4,i))
        response.write("<hr>")
next
不管多累,我还得坚持

TOP

getRows的使用看数据量的。

测试时,可以:
从几万条到几百万条的数据量试试。
从一个人到几千人同时在线的情况。

压力测试有工具的。

TOP

当然有人可能会说我要使用“fieldname as '标题'”的方式来自动显示标题,有没有办法呢,我们可以使用
复制内容到剪贴板
代码:
<!--#include file="conn.asp" -->
<%
sql = "Select a as '标题',b as '姓名' from cnarticle"
opendatabase
rs.Open sql,conn,1,1
   If not Rs.eof then
             Thedata=Rs.GetRows(-1)
             TheFieldCount=rs.fields.count
                For i=0 to TheFieldCount-1
                    TheFieldList = TheFieldList & Rs.fields(i).name & ","
                Next
             Closedatabase
             Num=ubound(Thedata,2)
             TheField = split(TheFieldList,",")
    for i=0 to Num
      for j=0 to TheFieldCount-1
        response.write("<br />"&TheField(j)&"是:"& Thedata(j,i))
      next
      response.write("<hr>")
    next
   Else
             Closedatabase
             response.write("暂时还没有文章")
   End If
%>
如果你所有的表单列表显示的方式与这个差不多,那么我们只需改动SQL语句就可以了,再把以上内容作为FUNCTION或SUB,直接调用,大大地提高了开发效率,这个也是当初只是把打开\关闭数据库操作作为单独函数的初衷了
不管多累,我还得坚持

TOP

使用getRows读取大数据量效率的下降问题确实应该使用MoveNext会好得多,但是对于一般的ASP列表页面我们不需要,或者可以通过优化SQL语句来提高性能,比如从几万条数据中读取记录,不应该把几万条记录都拿出来,往往每次只取几十或者上百条,这样的操作只需对SQL语句进行优化
不管多累,我还得坚持

TOP

一般Recordset中的数据SELECT后存在缓存中,从缓存中取数据速度较快。这就意味着,我们在显示数据时,预先读取几十页或上百页的数据,放在缓存中,充分满足用户的需求,用以减少服务器检索数据的代价。

TOP

对于大数据量,使用MoveNext进行读取会快得多。但并非所有的数据读都适合。之前说的办法在某些方面还是优于MoveNext方法的,毕竟不可能面面俱到,每种方法都有它的优点的

[ 本帖最后由 wowhhz 于 2007-8-6 09:56 编辑 ]
不管多累,我还得坚持

TOP

个人觉得应对大量数据时首先应该对SQL的语句进行优化.
如果你把海量数据SELECT * 读出.你的程序在优化,你能减少这些数据所占用的资源吗
为什么不(select top)读出自己所需的数据呢

TOP

如果不是取大数据量,使用我的方法确实会方便不少
<%
sql = "Select top 100 * from cnarticle"
set loadData=new DataTable
Thedata=loadData.SelectData(sql)
%>
这就完成了数据读取操作,开发和维护方面比较方便

[ 本帖最后由 wowhhz 于 2007-8-7 13:33 编辑 ]
不管多累,我还得坚持