vb.net перебирает результаты запроса

Я знаком с тем, как VB6 ADO обрабатывает SQL-запросы и перебирает результаты набора записей.

Однако как правильно запросить сервер, просмотреть результаты и удалить мой запрос в VB.Net? Все способы, которые я использовал, кажутся нестабильными и вылетают случайным образом.

Я использовал следующий код:

Public Function GetSQLTable(ByVal strSQL As String) As DataTable
    Dim table As New DataTable
    Dim adapt As SqlDataAdapter

    Try
        adapt = New SqlDataAdapter(strSQL, gconIntegration)
        adapt.Fill(table)
    Catch ex As Exception
        LogError("GetSQLTable: " & ex.ToString(), "SQL: " & strSQL)
    End Try

    Return table
End Function

И используя это так:

 Dim dt As DataTable
 Dim lngRow As Long
 Dim current As DataRow
 Dim lngContact As long

 Try
        dt = GetSQLTable(strSQL)
        For lngRow = 0 To dt.Rows.Count - 1
            current = dt.Rows.Item(lngRow)
            lngContact = current.Item("indvid") 
            DoSomething(lngContact)
        Next
Catch ex As Exception
    LogError("FindContact: " & ex.ToString(), "SQL: " & strSQL)
    lngContact = -1     
 Finally
    current = nothing
    dt = nothing

person Jeff Davis    schedule 27.02.2009    source источник


Ответы (1)


Я подозреваю, что проблема связана с тем, как вы управляете своим gconIntegration соединением. Вы слишком стараетесь продолжать использовать ту же самую связь. Было бы полезно посмотреть, где он живет.

Лучше получить «новые» соединения из пула и позволить .Net позаботиться об этом за вас.

Кроме того, в вашем общем коде «GetSQLTable» отсутствует важная часть: он не позволяет устанавливать параметры, что говорит мне о том, что вы встраиваете их непосредственно в свои строки запроса. Это рецепт катастрофы: это приведет к дырам в безопасности Sql-инъекций.

Еще одно: не устанавливайте объекты в Nothing в .Net. Либо утилизируйте их, если это необходимо, либо позвольте им выйти за рамки самостоятельно.

Вот мой обычный метод извлечения таблицы данных из таблицы данных:

Function GetSomeData(ByVal Table2ID As Integer)
    Dim result As New DataTable

    Dim sql As String = "SELECT Column1,Column2 FROM [Table1] WHERE Table2ID= @Table2ID"

    Using cn As New SqlConnection( GetConnectionString() ), _
    Using cmd As New SqlCommand(sql, cn)

        cmd.Parameters.Add("@Table2ID", SqlDbType.Int).Value = Table2ID

        Using rdr As SqlDataReader = cmd.ExecuteReader()
           result.Load(rdr)
        End Using
    End Using
    return result
End Function

Некоторые примечания к этому коду:

  • Оператор Using гарантирует, что связанный объект будет размещен в соответствующем End Using.
  • Параметры запроса строго типизированы и никогда не подставляются непосредственно в строку запроса, даже когда они передаются на сервер. Данные Sql и код Sql никогда не смешиваются.
  • Вам нужна отдельная функция для каждого запроса, который вам нужно отправить. Это действительно хорошо, так как приводит к созданию строго типизированного интерфейса для вашей базы данных. В идеале все эти функции принадлежат одному классу, а функция GetConnectionString является частной для этого класса. Доступ к базе данных не происходит за пределами этого уровня данных.
person Joel Coehoorn    schedule 27.02.2009
comment
gconIntegration — это глобальное соединение. То есть вы говорите, что одно соединение для всех моих операций чтения и письма не является оптимальным вариантом? - person Jeff Davis; 28.02.2009
comment
SQL Injection на самом деле не проблема, если это не веб-приложение (на самом деле это скомпилированный exe) - person Jeff Davis; 28.02.2009
comment
Правильно - этот дизайн заставляет вас выполнять всю работу с базой данных последовательно. Это особенно плохо для веб-сайта, где все запросы находятся в одном приложении. .Net объединяет соединения для вас в фоновом режиме, поэтому нет необходимости поддерживать глобальное соединение. - person Joel Coehoorn; 28.02.2009
comment
Да, внедрение является проблемой в настольном приложении. Пользователи по-прежнему могут вводить плохие вещи в текстовые поля. - person Joel Coehoorn; 28.02.2009
comment
Даже с настольными приложениями вам все равно не нужен глобальный объект подключения. Извлечение данных из базы данных может быть очень медленным, поэтому желательно иметь возможность делать это параллельно. - person Joel Coehoorn; 28.02.2009
comment
Кроме того: параметризованный запрос обычно работает немного лучше, потому что сервер кэширует план выполнения и сохраняет шаг компиляции. - person Joel Coehoorn; 28.02.2009
comment
Очень интересно. Спасибо за подробный ответ. - person Jeff Davis; 28.02.2009