2009-02-07 3 views
1

Я делаю много звонков в таблицы базы данных через ADO. В духе хранения вещей DRY я написал следующие функции, чтобы вернуть массив значений из набора записей. Является ли этот заяц мозгом? Я использую его в основном для захвата набора значений combo-box и тому подобного, никогда не для огромных значений. Пример использования (обработка ошибок удалена для краткости):критика кода - я создаю машину Rube Goldberg?

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 

Вопросы, которые я бы являются: смысл абстрагироваться все творение записей объекта/открытия/обработки ошибок в свой собственный вызов функции, как это? Я строю машину Рубе Голдберга, где кто-нибудь, поддерживающий этот код, проклинает мое имя?

Должен ли я просто сосать его и написать некоторые макросы, чтобы выплюнуть код соединения ADO, а не попробовать сделать это в функции?

Я очень новичок в asp, поэтому у меня есть дыры в его возможностях/лучших практиках, поэтому любой ввод будет оценен.

ответ

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) 
+0

Не знал метода GetRows. , , Благодарю. – GoingTharn

0

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

+0

Потому что он кладёт в выпадающий список. Обычная практика Windows. Если это то, что делает функция, то зачем обрабатывать цикл снова вне функции. – jmucchiello

4

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

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

+0

Ahhh, спасибо. Я считаю, что лучше всего создать экземпляр массива после вызова набора записей и создать экземпляр с помощью getSQLArray = Array (objRS.RecordCount) Таким образом, мне не нужно вообще удалять. – GoingTharn