我通过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的新手,因此我的功能/最佳实践漏洞,所以任何输入都会受到赞赏。
答案 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)
是的,分解常见任务是有意义的。我认为这个总体思路没有任何问题。我想知道为什么你要返回一个由分隔符分隔的字符串数组;你也可以返回一个数组数组。