Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Что еще можно сказать о БД?


Visual Basic: новости сайтов, советы, примеры кодов

VBNet.Ru
Выпуск от Павла Сурменка



Что еще можно сказать о БД?

Что-то давненько  не писал... В этом выпуске покажу пример использования отсоединенной модели данных и выполнения запросов без получения набора данных.

Отсоединенная модель

При получении данных из БД с помощью DataReader записи считываются по одной (при вызове метода Read), и в течение всего времени получения и обработки данных соединение с БД должно быть открыто. Это не всегда удобно.

Отсоединенная модель данных предполагает, что данные единовременно загружаются в некий объект, после чего можно работать с локальной копией данных, а соединение закрыть. В этом случае, кстати, хорошим тоном считается не держать  соединение открытым в течение всей работы приложения, а открывать соединение как можно позже и закрывать как можно раньше (скажем, открыть перед получением данных, закрыть сразу после получения данных, а когда понадобится произвести еще какую-то операцию, то опять открыть-выполнить-закрыть). Это особенно важно в тех приложениях, которые используются большим количеством пользователей (например в веб-сайтах).

Ниже приведен пример получения данных с помощью DataAdapter, сохранение их в DataTable (это как раз то самое отсоединенное локальное хранилище данных) и последующую работу с ними уже при закрытом соединении с БД.

'DataTable - здесь будут храниться данные

Dim DT As DataTable

 

'Строка соединения

Dim ConnectionString As String = "Password=*******;Persist Security Info=True;User ID=sa;Initial Catalog=test;Data Source=SURMENOK\SQL2005"

 

'СОздаем соединение

Using Conn As New SqlConnection(ConnectionString)

 

    'Открываем соединение

    Conn.Open()

 

    'Текст SQL-запроса

    Dim SQL As String = "SELECT UserName, Email FROM Users ORDER BY UserName ASC"

 

    'Создаем команду

    Dim Comm As New SqlCommand(SQL, Conn)

 

    'Создаем DataAdapter

    Dim DA As New SqlDataAdapter(Comm)

 

    'Создаем DataTable

    DT = New DataTable()

 

    'Сливаем данные в DataTable

    DA.Fill(DT)

 

    'На этом моменте данные уже получены и соединение с сервером можно закрыть

End Using

 

'Перебираем все записи в DataTable

For Each DR As DataRow In DT.Rows

    'Получаем значения полей записи

    Dim UserName As String = CType(DR("UserName"), String)

    Dim Email As String = CType(DR("Email"), String)

 

    'Выводим результат в консоль

    Console.WriteLine("{0} {1}", UserName, Email)

Next

Есть конечно в этом подходе и очевидные минусы. К примеру, большие затраты оперативной памяти для хранения отсоединенного набора данных. В примере выше, если таблица Users имела бы несколько миллионов записей, то наблюдались бы большие тормоза.

Еще один недостаток в том, что DataAdapter работает существенно медленней DataReader. Это и понятно: DataAdapter сам использует DataReader для чтения данных из БД, а еще ведь надо создать в DataTable нужную структуру данных, добавить в нее данные (а это небыстрая операция, учитывая, что данные DataTable хранит в формате XML)… В общем, мрак. Поэтому в веб-сайтах (которые очень критичны к скорости) чаще применяют ля чтения данных DataReader, а отсоединенная модель находит большее применение в Windows-приложениях.

Обращение к БД без возврата набора данных

Некоторые SQL-запросы не предполагают возврат таблицы данных, а возвращают только одно значение, или вообще ничего. Естественно, хочется использовать для выполнения этих запросов более простые методы, чем для получения набора данных. И они есть: это, соответственно, методы ExecuteScalar и ExecuteNonQuery класса xxxCommand.

И внагрузку продемонстрирую параметризированные запросы :)

Пример получает кол-во записей в таблице Users и удаляет одну запись с указанным значением UserName.

'Строка соединения

Dim ConnectionString As String = "Password=*******;Persist Security Info=True;User ID=sa;Initial Catalog=test;Data Source=SURMENOK\SQL2005"

 

'Создаем соединение

Using Conn As New SqlConnection(ConnectionString)

 

    'Открываем соединение

    Conn.Open()

 

 

 

 

    'Текст SQL-запроса

    Dim SQL As String = "SELECT COUNT(ID) FROM Users"

 

    'Создаем команду

    Dim Comm As New SqlCommand(SQL, Conn)

 

    'Выполняем запрос

    Dim Count As Int32 = CType(Comm.ExecuteScalar(), Int32)

 

    Console.WriteLine(String.Format("Кол-во юзеров: {0}", Count))

 

 

 

 

    'Текст SQL-запроса

    SQL = "DELETE FROM Users WHERE UserName = UserName"

 

    'Создаем команду

    Comm = New SqlCommand(SQL, Conn)

 

    'Задаем параметры

    Comm.Parameters.Add("@UserName", SqlDbType.NVarChar, 256).Value = "Vasya"

 

    'Выполняем запрос

    Comm.ExecuteNonQuery()

End Using

 

Вот так вот. Что еще на эту тему сказать – не знаю. В целом всё сказал :) Детали смотрите в MSDN.

Есть еще такая вещь как типизированные DataSet’ы. Есть еще такая вещь как Table Adapters (появились в VS 2005). Это всё – просто средства для автогенерации кода: типизированная оболочка для DataSet, адаптеры с методами получения данных, удаления/изменения/вставки записей. Всё это создается легко, с помощью мастеров в VS. Это очень удобно для быстрой разработки простеньких программ, но для чего-то серьезного совсем непригодно: инструменты очень негибкие и громоздкие. Можете попробовать сами: Project Add Item, тип объекта выбираете DataSet, а дальше уже в мастере разберетесь что к чему.

 

Пишите письма! Только вот я ранее не предупредил... Не нужно писать о VB6, VBA, классическом ASP и т.д. Это мне уже давно неинтересно, и лучшее, что я вам отвечу – это посоветую, кто за скромную плату в твердой валюте сможет помочь. То же самое насчет «помогите написать программу,  которая ...». Мне будут интересны только конкретные вопросы по узким темам в области .NET, T-SQL, регулярных выражений,  XML/XSLT/XPath, JS и т.д. – на конкретные вопросы я отвечать люблю :)

 

Павел Сурменок

VBNet

Web Reflection

 


В избранное