критика кода - я создаю машину Рубе Голдберга? - PullRequest
1 голос
/ 07 февраля 2009

Я делаю достаточное количество обращений к таблицам базы данных через ADO. В духе сохранения СУХОГО я написал следующие функции для возврата массива значений из набора записей. Это заяц мозг? Я использую его в основном для получения набора значений комбинированного списка и т. П., А не для огромных значений. Пример использования (обработка ошибок удалена для краткости):

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 ]

4 голосов
/ 08 февраля 2009

В этом нет ничего плохого. Библиотеки ADO не очень хорошо спроектированы, и их непосредственное использование занимает слишком много строк кода, поэтому у меня всегда есть несколько служебных функций, облегчающих выполнение обычных задач. Например, очень полезно создать себе функцию «ExecuteScalar», которая запускает SQL, который возвращает ровно одно значение для всех тех SELECT COUNT (*), которые вы можете сделать.

НО - ваша функция myPush крайне неэффективна. ReDim Preserve занимает много времени, потому что он должен перераспределять память и копировать все. Это приводит к производительности O (n 2 ) или к тому, что я называю алгоритмом Shlemiel the Painter . Рекомендуется начинать с диммирования, скажем, массива, в котором есть место для 16 значений, и удваивать его при каждом заполнении. Таким образом, вам не нужно будет звонить ReDim Preserve больше, чем Lg 2 n раз.

2 голосов
/ 08 февраля 2009

Интересно, почему вы не используете 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)
0 голосов
/ 07 февраля 2009

Да, имеет смысл выделять общие задачи. Я не вижу ничего плохого в общей идее. Мне интересно, почему вы возвращаете массив строк, разделенных разделителем; Вы также можете вернуть массив массивов.

...