代码评论 - 我是否正在创建Rube Goldberg机器?

时间:2009-02-07 18:17:42

标签: asp-classic vbscript ado

我通过ADO对数据库表进行了大量调用。 本着保持DRY的精神,我编写了以下函数来从记录集返回一个值数组。 这是野兔吗? 我主要用它来抓取一组组合框值等,永远不会用于巨大的值。示例用法(为简洁起见,删除了错误处理):

Function getEmployeeList()
    getEmployeeList= Array()
    strSQL =  "SELECT emp_id, emp_name from employees"
    getEmployeeList = getSQLArray( strSQL, "|" )
End Function

然后我只对返回的数组做任何我想做的事。

Function getSQLArray( SQL, delimiter )
'*************************************************************************************
' Input a SQL statement and an optional delimiter, and this function
' will return an array of strings delimited by whatever (pipe defaults)
' You can perform a Split to extract the appropriate values. 
' Additionally, this function will return error messages as well; check for 
' a return of error & delimiter & errNum & delimiter & errDescription
'*************************************************************************************
    getSQLArray = Array()
    Err.Number = 0
    Set objCon = Server.CreateObject("ADODB.Connection") 


    objCon.Open oracleDSN


    Set objRS = objCon.Execute(SQL)

    if objRS.BOF = false and objRS.EOF = false then
        Do While Not objRS.EOF
            for fieldIndex=0 to (objRS.Fields.Count - 1)
                    If ( fieldIndex <> 0 ) Then
                        fieldValue = testEmpty(objRS.Fields.Item(fieldIndex))
                        recordString = recordString & delimiter & fieldValue
                    Else 
                        recordString = CStr(objRS.Fields.Item(fieldIndex))
                    End If
            Next 
            Call myPush( recordString, getSQLArray )
            objRS.MoveNext
        Loop
    End If
    Set objRS = Nothing
  objCon.Close
  Set objCon = Nothing
End Function

Sub myPush(newElement, inputArray)
    Dim i
    i = UBound(inputArray) + 1
    ReDim Preserve inputArray(i)
    inputArray(i) = newElement                                          
End Sub


Function testEmpty( inputValue )
    If (trim( inputValue ) = "") OR (IsNull( inputValue )) Then 
      testEmpty = ""
    Else
        testEmpty = inputValue 
    End If
End Function

我的问题是: 将所有记录集对象创建/打开/错误处理抽象到它自己的函数调用中是否有意义? 我是否正在构建Rube Goldberg机器,维护此代码的任何人都会诅咒我的名字?

我应该把它搞砸并编写一些宏来吐出ADO连接代码,而不是尝试在函数中进行吗?

我是asp的新手,因此我的功能/最佳实践漏洞,所以任何输入都会受到赞赏。

3 个答案:

答案 0 :(得分:4)

按照自己的方式行事并没有错。 ADO库并没有真正设计得很好,直接使用它们需要太多的代码,所以我总是有一些实用程序函数可以更容易地完成常见的工作。例如,让你自己成为运行SQL的“ExecuteScalar”函数是非常有用的,它恰好返回一个值,对于你可能做的所有SELECT COUNT(*)。

但是 - 您的myPush功能非常低效。 ReDim Preserve需要很长时间,因为它必须重新分配内存并复制所有内容。这导致O(n 2 )性能,或我称之为Shlemiel the Painter算法。建议的最佳做法是从调暗开始,例如,一个可容纳16个值的数组,并在填充它时将其加倍。这样您就不必再次调用ReDim Preserve而不是Lg 2 n 次。

答案 1 :(得分:2)

我想知道你为什么不使用GetRows?它返回一个数组,您可以在此处找到更多详细信息:http://www.w3schools.com/ado/met_rs_getrows.asp

关于GetRows的一些注释:

Set objRS = Server.CreateObject ("ADODB.Recordset")
objRS.Open cmd, , adOpenForwardOnly, adLockReadOnly

If Not objRS.EOF Then
   astrEmployees = objRS.GetRows()
   intRecFirst   = LBound(astrEmployees, 2)
   intRecLast    = UBound(astrEmployees, 2)

   FirstField  = 0
   SecondField = 1
End If

'2nd field of the fourth row (record) '
Response.Write (SecondField, 3)

答案 2 :(得分:0)

是的,分解常见任务是有意义的。我认为这个总体思路没有任何问题。我想知道为什么你要返回一个由分隔符分隔的字符串数组;你也可以返回一个数组数组。