1

我正在通过 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 很陌生,所以我在它的功能/最佳实践中存在漏洞,所以任何输入都将不胜感激。

4

3 回答 3

4

按照自己的方式做事没有错。ADO 库的设计并不是那么好,直接使用它们需要太多的代码行,所以我总是有一些实用函数可以更容易地做一些常见的事情。例如,为自己创建一个“ExecuteScalar”函数来运行恰好返回一个值的“ExecuteScalar”函数是非常有用的,因为你可能会执行所有这些 SELECT COUNT(*)。

但是-您的myPush功能效率极低。ReDim Preserve需要很长时间,因为它必须重新分配内存并复制所有内容。这会导致 O(n 2 ) 性能,或者我称之为Shlemiel the Painter算法。推荐的最佳做法是首先调暗,例如,一个有 16 个值空间的数组,然后在填充时将其大小加倍。这样你就不必调用ReDim Preserve超过 Lg 2 n次。

于 2009-02-07T22:01:11.250 回答
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)
于 2009-02-08T18:21:15.827 回答
0

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

于 2009-02-07T18:25:47.457 回答