Книги, научные публикации Pages:     | 1 |   ...   | 3 | 4 | 5 |

том 1 альманах программиста Тематический сборник материалов Library и Magazine ADO.NET SQL Доступ к из приложений Составитель Ю. Е. Купцевич Москва 2003 fii. P У С P i К УДК 004.45 ББК ...

-- [ Страница 5 ] --

Optional As With '- Источник данных '- данных * данных ffl.slлIAppName, ra.sIHIFuUPath Идентификатор * = m.sINIFullPath) Функция (рис. 4) сначала проверяет, не сохранен ли пара метр в MTS Если да, он считывается оттуда, и не откры вается. Иначе GetlNIValue параметр из закрывает файл, сохраняет параметр в SPM и передает его через возвращаемое чение. Применение устраняет издержки, связанные с чтением INI файла каждом вызове Рис. 4. Функция GetlNIValue As As Optional As As Variant Const As String = & On Err Const As 1" As As As Dim As Dim As Boolean Dim As см. след.

ADO и XML: уровня доступа к данным Рис. 4. Функция As "- группу свойств * Set * & & Process, Set * & & If Set - New *- в INI путь, по If & & & = Value sKey) Value - Walue Walue End If oIHI Nothing Set - Nothing Err;

Err, Error, Выполнение SQL-команды Как только подпрограмма получает параметры базы данных, метод создает и открывает Connec tion. Затем, используя открытый объект Connection, метод создает и от крывает записей. Набор записей открывается как клиентс кий набор и сразу же отсоединяется от объекта Connection (рис. 5).

В заключительной части кода на рис. 5 данные форматируются в соответ ствующую структуру. Если вызывающему приложению требуется ADO набор то на этом этапе набор просто передается приложению. В ином случае функция (рис. 6), которая возвращает форматированные данные.

Доступ к данным из Рис. 5- Открытие и отсоединение набора записей *- Select oRs = ttew With Получаем отсоединенный набор вместо "- так как для предоставляются * = ' '- Отсоединяем его Set With набор If Set * oRs * End If Рис. 6.

Private As As Variant Const Error - формат данных If If Then Select Case If * If Case * Select End If End If см. след. стр.

ADO и XML: уровня доступа к данным Рис, 6. Функция Exit Error, End Функция ConstructReturnData просто определяет необходимый формат данных и создает двухмерный массив методом GetRows набора записей или форматирует данные в XML через функцию Функция BuildXML вызывает метод BuildXML объекта который формати рует ADO-набор записей в XML. Для этого он просматривает поля на бора записей, считывая а затем перебирает строки и поля, считывая сами данные. Для создания XML метод использует объект MSXML.DOMDocument.

Форматирование в XML Форматируя выходной XML, BuildXML сначала создает корневой тэг затем Ч тэг , в котором будут указаны все атрибуты полей. Внутрь тэга вкладывается тэг , который в свою очередь содержит тэги :

Создаем XML-документа Set = Х With Создаем метаданные '- Создаем '- Fields Для каждого поля из набора записей формируется один тэг с ат рибутами Type, IsNullable и т. д. На рис. 7 показан код, который со здает эти атрибуты и сопоставляет их тэгу Далее следует тэг с тэгом внутри. Тэг содержит тэги для каждой строки данных. Каждому тэгу присваива ется уникальный индекс. Тэг также включает тэг внутри которого расположены тэги для каждого поля из ADO-набора за писей. На рис. 8 показано, как данные объединяются в XML-документ.

Доступ к данным из приложений Рис. 7. Создание атрибутов тэга Для Recordset для создания 0 To - t атрибуты метаданных With '- атрибут '- Создаем атрибут.

Рис. 8. Создание элементов данных в XML Х '- Создаем Data Rows '- With Do While Not к - Создаем узел Row атрибут Index узел Fields '- '- поля Recordset Field For 0 To - '- Field см. след. стр.

ADO и XML: создание уровня к данным Рис, 8. Создание элементов данных в With With атрибут '- Создаем атрибут Name = & "" End Next End With End With End With Set = Nothing.

Помните, что вы вправе изменять формат по своему усмотрению. Я выбрал простой формат с отделением метаданных от самих данных. Одна ко вы можете избавиться от тэга , создав атрибуты с метадан ными в элементах fields, в тэг . А если вам не нужны метаданные, их можно вовсе исключить. В этом и заключается прелесть он позволяет определять любой формат возвращаемых данных!

Заключение В итоге у вас появился компонент для доступа к данным, абсолютно неза висимый от вызывающих приложений. Вы можете использовать Data Manager в нескольких бизнес-компонентах, которые будут работать с раз ными серверами баз данных и получать данные в разных форматах.

Чтобы поэкспериментировать с моим кодом, вам понадобится лишь Visual Basic и база данных Pubs из SQL Server. Разумеется, вы можете модифи цировать этот код под другие базы данных.

Джонни Папа (Johnny Papa) Ч вице-президент компании MJM Investigations по разработке программного обеспечения (Роли, штат Северная Каролина), автор нескольких книг по ADO, XML и SQL Server. Часто выступает на конфе ренциях, в том числе на VSLive. С ним можно связаться по адресу Марк Герлах Сбор информации от Web-сайтов и каталогов с применением Visual Basic и Visual Basic просто напичкан возможностями, которых не было в прежних версиях этого языка В частности, он поддер живает новую модель потоков (threading создание нестандартных классов (custom>

Учитесь использовать эти возможности на примере извлекаю щего информацию с Web-страниц для последующего индексирования.

В статье также обсуждаются доступ к базам данных, файловый расширение классов объектов и применение на формах свойств ти (transparency) и непрозрачности (opacity).

Когда начинаешь работать с новым или с сильно изменившимся какое-то время уходит на новых интерфейса, синтаксиса, функ ций и других средств. Чтобы приобрести опыт в использовании Visual Basic я решил переписать приложение из каталога своей а заодно расширить его функциональность и на практике продемонстри ровать некоторые новые языковые средства.

В этой статье описывается переработанная версия робота Ч приложения, изначально написанного на Visual Basic 6.0. Исходное приложение собира ло необработанный HTML-текст из различных источников в Web, после * Публиковалось в Magazine/Русская Редакция. 2002. №4 (октябрь). Ч Прим.

Сбор от и синтаксического разбора помещало информацию в набор таблиц базы дан ных и определяло, какая информация может пригодиться пользователю.

Приложение следовало инструкциям, считываемым из файла robots.txt на сайте, сохраняло полный HTML-код сайта на локальном жестком диске и вело журнал любых ошибок и изменений в структуре сай та. В новой названной мной Spider (лпаук), я стремился сохранить как можно больше функциональности прежней версии и, кро ме того, хотел хорошенько проверить возможности Microsoft,NET Frame work. Заметьте, что я создавал Spider во второй бета-версии Visual Studio а тестировал уже в финальном выпуске Visual Хотя исходный продукт был неплохо продуман, я все же хотел дополнить его возможностями, которые трудно на Visual Basic 6.0. Одна из них Ч истинно многопоточный объект (multithreaded object), способ ный по страницам независимо от родительского приложения (и от остальных потоков) и периодически сообщающий приложению инфор мацию о своем состоянии. Создание такого объекта Ч прекрасное приме нение потоков.

В этой статье мы обсудим лишь ключевую функциональность приложе ния, демонстрирующую приемы, для Visual Basic об ход страниц с многопоточности, управление через файл robots.txt, исключение файлов с неизвестными расширениями, обработка потоковой информации, передаваемой через Интернет, модификация пользовательского интерфейса (UI), протоколирование ошибок и опера ции с базами данных. Ясно, что в окончательной версии программы воз можностей будет куда Кроме того, интерфейс и функции программы зависят от конкретного при менения робота. Так, модуль синтаксического анализа (parsing module) бесполезен, если от программы требуется лишь запись копии HTML-по тока на локальный Если робот планируется использовать в много процессорной системе, введение лимита на пять потоков явно ограничит его возможности. Так что приложения типа обычно приходится создавать в нескольких версиях, отвечающих разным (иногда противопо ложным) требованиям. Я решил предусмотреть максимум возможностей настройки, при этом поставив себе задачу обеспечить поддержку разнооб разных файловых форматов, HTML-типов и инструкторов синтаксичес кого анализа (parsing instructors).

Кодирование приложения Я начал с того, что открыл Visual Studio создал новый проект Visual Basic на основе шаблона Windows Application, ввел название нового про Доступ к из приложений (Spider) и щелкнул ОК. Потом создал UI. Я решил заняться сначала им, чтобы четко понять, каким увидят робот мои пользователи;

к тому же он послужит мне точкой.

создания формы не сильно отличался от такового в предыдущих версиях Visual Basic. Но, поскольку Visual Basic показывает исход ный код, используемый им для построения элементов управления на фор ме (который прежде прятался в начале я обнаружил, что теперь, скопировав исходный код формы и его в можно немедленно воссоздать элементы управления формы на форме FormB. Visual Basic 6.0 тоже позволял переносить исходный код, но элементы управления надо было отдельно.

Создав формы, я добавил ним элементы управления, придав главному окну приложения вид как на рис. 1, а окну Options Ч как на рис. 2.

Рис. 1. Главное окно приложения я добавил необходимые классы и модули. Щелкнув правой кнопкой мыши имя проекта в Solutions Explorer, я создал модуль и два класса;

и Разделавшись со структурами можно было приступать к написанию кода.

Сбор от Web-сайтов каталогов In Perse Рис. 2. Окно Options Создание потоков Как я уже говорил, приложение было решено переделать в основном ради многопоточности, вот и займемся сю. Потоки создаются двумя главными компонентами: самим приложением и классом, предназначенным для по лучения страниц с Web-сайта. Общая архитектура Spider и взаимосвязи его компонентов показаны на рис. 3.

clsSpider clsSpider clsSpider clsSpider поток 1 2 3 лоток 4 ПОТОК Рис. 3. Модель потоков Spider Spider дает возможность пользователю выбирать, сколько активных пото ков будет порождено при обработке. В этом приложении число потоков ограничено пятью, поскольку вряд ли кто из читателей будет тестировать мою программу на системе. Spider создает столько индивидуальных объектов clsSpider, сколько запрашивает пользователь, и следит за состоянием каждого потока. В свою очередь потоки извлекают HTML с заданных страниц (при необходимости проводя синтаксический анализ), записывают его в локальную базу данных и возвращают приложе 374 Доступ к из новые ссылки, которые нужно обработать. В ходе работы каждый по ток периодически обновляет в главном приложении сведения о своем со стоянии через обработчик события eh Status, который отражает на главной форме сведения о потоках и ход обработки больших файловых потоков (file а также сообщает, какие файлы уже обработаны. По окончании обработки все потоки автоматически завершаются, поэтому самостоятельно вызывать метод не требуется.

Безопасность кода в многопоточной среде (thread-safe крайне важ на для подобных приложений, иначе потоки и програм ма не то что будет работать медленнее однопоточной, а просто рухнет.

Чтобы не допустить этого, команда разработчиков ввела в Visual Basic поддержку блокировки Функция SyncLock принимает выражение, содержащее объект, который нужно блокировать. Для примера взгляните на код обработчика события в (исходный код к этой статье можно скачать с msdn.microsoft.com/msdnmag/code02.asp в разделе за октябрь). В данном случае он заставляет систему проверить, можно ли получить блокировку на массив m_sPages (в нем хранится список еще не полученных страниц):

SyncLock ' Сюда вставляется код, имеющий дело с блокировкой SyncLock End SyncLock Поскольку все три обработчика событий в Spider срабатывают из-за вызо ва метода они выполняются в том же потоке, что и вызываю щий (в данном случае Ч в классе clsSpider), а не в потоке главного прило жения. Поэтому очень важно использовать метод SyncLock, чтобы к мас сиву единовременно обращался только один поток, иначе возможна взаимная блокировка потоков.

Если блокировку SyncLock нельзя получить немедленно, приложение ждет, пока не получит ее. Как только SyncLock попадает во владение про граммы, остальным потокам обращение к массиву m_sPages до освобождения блокировки SyncLock. Эта блокировка выполняет ряд вспомогательных функций, в частности определяет, присутствует ли рас ширение возвращаемых страниц в списке распознаваемых суффиксов. Но ее самая главная функция Ч добавление к массиву новых стра ниц, найденных текущим потоком и подлежащих извлечению и синтакси ческому анализу. Без SyncLock два потока могли бы одновременно таться добавить в массив новые элементы и записать в его верхнюю часть Речь о доступа потоков к ресурсам. Ч Прим. сост.

Сбор от и дублирующиеся значения. А это чревато системной ошибкой и даже поте рей еще необработанных страниц.

Важно отметить, что ни в коем случае нельзя использовать для блокирования потоков или процессов, изменяющих форму или элемент управления. Дело в том, что формы и элементы управления иногда ответ но обращаются к Такая ситуация скорее всего закончится взаимной блокировкой потоков. Однако обработчик ehThread Status использует SyncLock для блокирования формы перед обновлением ее элементов управления хода операции (progress bar cont rols). Поскольку два потока (или более) могут заблокировать друг друга при одновременном обращении к окну списка (listbox), важно блокиро вать форму на время ее Эта ситуация отлична от той, где SyncLock применяется к обновляющему форму. Применяя Sync Lock к самой форме, я добиваюсь того, чтобы два потока не мешали друг другу при обращении к ней. Блокировать при этой операции нет так как другие потоки в это время не обращаются к форме.

При щелчке Process приложение создает массив объектов Thread, Первый поток из массива извлекает страницу с целевого сайта, и обработчик обрабатывает полученную страницу, В это время Spider исполняет ожидая возврата управления от первого потока или появления новых значений в массиве Если первый поток возвращает не найдя новых приложение переходит к следующему выбранному сайту.

Как только в массиве появляются значения, из него выделяется страница неактивному потоку clsSpider;

при этом переданная на обработку, удаляется из и добавляется в массив m_sPagesDone.

Последний тоже проверяется перед запуском новых потоков, чтобы избе жать повторного извлечения уже обработанной страницы. Этот процесс продолжается, пока будут просмотрены все всех выбранных сайтов.

Поиск в потоке данных С в Visual Basic пришла поточной обработ ки (streaming). Поток данных (stream) Ч это байтов, поступающая в результате запроса из Интернета, файла или от устройства ввода-вывода, например от клавиатуры или мыши. Spider имеет дело с двумя типами потоков данных: потоками из Интернета ми) и файловыми потоками.

Концепция Интернет-потока сравнительно проста. Все Интернет-серверы передают клиенту потоки данных в виде в ответ на 376 Доступ к данным из приложений росы, посылаемые серверам. Чтобы дополнить робот этой функционально стью, я прежде всего импортировал библиотеку в начало своего класса строку:

Imports Затем создал Web-запрос:

Dim myReq As = Приложение посылает каждому потоку строку m_sURLToProcess с URL, который должен быть обработан этим потоком.

Далее я создал объект response:

Dim myResponse As = С этого момента у меня есть объект response, способный хранить поток HTML-данных с целевого сайта. Но мне нужно знать, какую страницу вер нул Например, в некоторых когда я запрашивал кор невой каталог сайта Web-сервер возвращал страницу по умолчанию ( Мне нужно знать эту страницу, чтобы отметить ее в базе данных и не тать повторно, если ссылка на нее встретится в другом потоке HTML-дан ных. Поэтому я делаю такой вызов:

= myResponse.

Потом мне пришлось решать еще одну проблему. Дело в том, что в теку щем состоянии поток данных непригоден к использованию. Входящие данные должны быть помещены в нечто вроде массива байтов или строки Ч во что-то, с чем я мог бы работать. Чтобы перевести их в такую форму, я создал для потока данных несколько хранилищ и вспомогательный объект Dim As Integer, As Byte = Dim br As New Содержимое потока данных поблочно извлекается в цикле:

- 1) Dim As Byte = 1: = Do Until = ReDim = 0, iContentLength) Preserve - 1) Сбор информации от и каталогов If > 0 Then 0, sTotalBuffer, iTotalBytes, Loop Обратите внимание на строку с RaiseEvent в конце цикла. Она сообщает программе, какая часть страницы уже преобразована из потока данных.

Помните: этот обработчик вызывается в том потоке, где выполняется clsSpider. Также обратите внимание на функцию 0, sTotalBuffer, iTotalBytes, Эта строка заменяет устаревший API-вызов memcpy, использовавшийся в прежних версиях Visual Basic. методом Аггау.Сору намного проще рабо тать. Указав исходный массив, начальный элемент, целевой массив, на чальную точку и копируемых байтов, я могу легко скопировать бло ки памяти без возни с API-функциями и внешними DLL, в кото рых они содержатся.

В реальной программе вы найдете оператор If, определяющий длину пото ка данных. Интернет-потоки бывают двух типов: с поддержкой поиска и без. В данном случае я предпочитаю рассматривать поиск как прокрутку:

в потоке с поддержкой поиска можно перемещаться по объекту потока вперед и назад, извлекая байты из любой позиции. Поток, не поддержива ющий поиск, допускает только однонаправленное перемещение. Код клас са clsSpider определяет, каков тип полученного потока и как обращаться с ним, чтобы извлечь из него информацию.

После этого кода в моем распоряжении остается строка sTo с полным листингом HTML-кода страницы, и я передаю эту стро ку различным функциям для обработки.

Обработка ошибок Теперь, когда базовая функциональность робота и класса clsSpider готова, пора заняться обработкой ошибок. В Visual Basic появились новые средства обработки ошибок, которые намного превосходят неуклюжие On Error Goto из прежних версий. Блоки Try, Catch и Finally позволяют ис пользовать в Visual Basic структурную обработку ошибок, Эти сред ства оказались весьма полезны в некоторых частях приложения Spider.

Так, функция ProcessRobots ищет в корне целевого Web-сервера файл robots.txt и возвращает код ошибки 5, если не может найти его. Было бы неплохо поместить в код этой функции нечто вроде:

378 Доступ к данным из приложений Catch When = ' Этот код просто сообщает, что файл Robots.txt не найден & & & & & & & & & & Err.Erl) Блоки Try/Catch можно в другие блоки. Это удобно, когда заранее известно о вероятности ошибок (в частности, из-за про блем с Web-серверами под управлением Unix или с некоторыми типами HTML-потоков). Хороший пример Ч метод Я создаю по ток в блоке Try. Если при этой ответственной операции возникнет какая-нибудь ошибка, следует завершить все активные потоки приложе ния и выйти из Б первый блок Catch включен код:

& & & & & Err.Erl) & & & & Сначала я добавляю код, известные мне ошибки, затем создаю вложенный блок Try/Catch для завершения индивидуальных токов:

Try Try i = To If Not Then Next i Catch i & & & & Err.Erl) WriteErrorLogC'StartThreading: & & & _ 4 & Err.Erl) End Try End Try В прежних версиях Visual Basic такое было попросту невозможно без на писания крайне запутанного кода.

Протоколирование ошибок Помимо блоков Try/Catch, обрабатывающих ошибки, мне нужен файл журнала для регистрации ошибок. Поэтому я создал функцию, записыва сообщения об ошибках в файл в корневом каталоге приложения, Сбор информации от и Это самый обычный текстовый файл, в котором для каждой ошибки со храняются дата и время, номер ошибки, описание, вызвавшая ее функция и номера ссылавшихся на строку, где возникла ошибка.

Я поместил функцию в файл Эта функция прекрасно иллюстрирует файловый Сначала я присваиваю имя файлу журнала:

Dim As String = & & Обратите внимание на метод Application. Startup Path: он заменил метод App.Path, применявшийся в прежних версиях Visual Basic.

Затем я открыл объект Writer, который позволяет добавлять текст к файловому потоку:

Dim As = Следующая строка создает безопасную в многопоточной среде оболочку объекта TextWriter, чтобы одновременное обращение нескольких потоков к этому объекту не закончилось их крахом:

Далее я записываю в файл строку и закрываю объект TextWriter:

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

Мой маленький Полная версия Spider поддерживает запись в базы данных SQL Server и уйму других форматов. Версия, описываемая в этой статье, ведет простую базу данных Microsoft Access. Для этого я должен был им портировать соответствующую базовую функциональность:

Imports Imports Imports Потом я создал переменную, содержащую строку подключения к моей базе данных:

Доступ к данным из приложений Public As String = Data & Для доступа к базе данных все готово. Поскольку мне не требовалось ни чего экстраординарного, я создал пару функций: (возвра щает объект DataReader только для чтения) и (выполняет строку с SQL-запросом к выбранной мной базе данных и возвращает вы зывающей функции число обработанных строк).

Функции drGetReadOnly и lExecuteSQL показаны на рис. 4 и рис. 5 соот ветственно. Они почти не отличаются друг от друга: drGetReadOnly ис пользует метод OLE-объекта DBCommand, a lExecuteSQL метод Рис. 4. drGetReadOnly ' DataReader из базы данных Function sSQL As As Try 2:

3: As = Hew cn) 4: Dim As = 5:

& & & 10: & & ": & & & Err.Erl) 500;

& & ": & & & Err.Erl) End Рис. 5.

Выполняет переданный SQL-оператор и возвращает строк As As Long Try As New As New cn) Dim As Long = IRecsAffected & & & & Err.Erl) 10: 4 & & см. след. стр.

информации от и Рис. 5, 4 & Err.Erl & vbCrLf & & & & Err.Erl & vbCrLf & sSQL) End Function Что случилось с ItemData?

В Visual Basic 6.0 я использовал свойство ItemData списков (listboxes) и полей со списками (comboboxes) для хранения информации о каждой строке. Чаще всего я помещал в него идентификаторы всех записей. Если мне нужно было хранить больше информации, приходилось создавать на бор (collection) и связывать каждый элемент с элементом списка или поля со списком. В Visual Basic этот подход заменен на другой, гораздо более удобный.

В Visual Basic я могу создать нестандартный класс (рис. 6). В опре делении класса я замещаю метод ToString, указывая, какое значение он должен возвращать, а также создаю в clsBoxOverride метод New, позволяющий передавать аргументы экземпляру этого класса.

Рис, 6. Класс clsBoxOverride класс для передачи данных списку сайтов в окне, Похож на функцию в стиле ItemData (ее больше нет Visual Basic но позволяет которые можно хранить с списка. для этого приходилось использовать, набор или массив.

Точка Option Explicit On Public>

Доступ к из Рис. 6.

As String, As = sSiteName = End Property String Value As Value End Set Get Return End Property Property As String Value As String) flLsSiteURL = Value Set Return End End Property Public Property As Long Set(ByVal Value As Long) flt_iSiteID Value End Set Set Return End Get End Property Overrides Function As String Return Function>

Сбор информации от и Обратите внимание, как определяются теперь свойства в классе (в данном случае Ч в Set и Get входят в тело каждого свойства;

Public Property As String Value As String) = Value End Set Return End Get End Property В Spider я использую эту функциональность в обработчике событии MouseMove, чтобы в списке вывести URL, сопоставленный с опи санием сайта.

Прозрачность и непрозрачность И последнее (по порядку, а не по важности). Благодаря двум новым сред ствам Visual Basic Ч прозрачность (transparency) и непрозрачность (opacity) Ч я смог украсить свое приложение ранее недоступными при мочками.

Я всегда мечтал о классном экране-заставке, который появлялся бы при запуске моего но все, что я мог бы сделать, ограничивалось прямоугольными окнами. И вот наконец-то команда разра ботчиков Visual Basic дала мне возможность управлять прозрачнос тью формы. По сути, это позволяет сделать один цвет на любой форме прозрачным. Я создал форму для экрана-заставки, поместив цветной ло готип на белый фон, и выбрал для свойства этой формы значение, соответствующее белому цвету. В итоге получилось то, что надо (рис. 7): белые области моего экрана-заставки стали прозрачными и сквозь них видно окно приложения.

Заодно я решил сделать так, чтобы главное окно приложения проявлялось на экране. Для этого используется новое свойство Opacity форм:

' формы, ' чтобы она постепенно проявилась на = О For i = 1 То 100 Step = i / Next i = Доступ к из приложений ment document. is a Th merit. This a a document.

ment is a is a Th This document. Th test Th Th Th ment. is test а document Th ment. is a test document Th This is a document. is a document Th This i? document. is a Th ment a Th Рис. 7. Прозрачность формы в действии Значение свойства Opacity может быть дробным и меняется от 0 (форма полностью невидима) до 1 (форма полностью видима). Блок кода, пока занный выше, увеличивает значение Opacity с шагом 1/10 до тех пор, пока форма не станет видимой.

Обратите внимание на строку Если ее удалить, фор ма почти моментально станет видимой. Эта строка фактически замедляет процесс проявления формы.

Заключение В настоящее время клиенты моей компании используют Spider для сбора информации с региональных и сайтов.

После небольшой доводки Spider сможет получать списки адресов из об щедоступного справочника Yellow Pages или собирать статьи по опреде ленной тематике со всей Web. Его можно было бы даже для доставки сообщений, публикуемых в телеконференциях на серверах ново стей. Spider способен извлекать любые Web-страницы (естественно, если у вас есть разрешение на копирование материалов, защищенных авторс ким правом). Полученную информацию можно поместить в базу данных для дальнейшего анализа.

В Visual Basic появилась уйма новых и просто замечательных функ ций. Проявив немного настойчивости, со временем вы научитесь пользо ваться каждой из этих функций. Более совершенная обработка и поддержка массивов, фокусы с и средства для работы с потоками дан ных Ч лишь часть инструментов, которые дает вам Visual Basic Вас ждет много потрясающих открытий!

Марк Герлах (Mark Gerlach) Ч директор отдела продуктов калифорнийской компании Optigon Technical поставщика ний Microsoft Solution Provider). Марк Ч обладатель сертификатов MCSD и MCDBA. С ним можно по адресу или mgerlach@mostwantedsoftware.com.

Кен Спенсер Управление транзакциями между компонентами Отвечая на вопросы, автор объясняет, как управлять транзакциями в не используя Этот вариант применим в том случае, если вы работаете только с одной базой данных.

В этом месяце я углублюсь вопрос одного из читателей о относящийся к приложениям как Web, так и Windows. Рад сообщить, что у меня наконец появилась финальная версия Visual Studio и Micro soft О бета можно забыть!

Вопрос Прочитал колонку (за февраль 2002 г.) по и в ( Вы что если компонент всегда выполняет только в одной базе данных, то для реализации этих транзакций не обязательно применять СОМ+ Ч можно использовать Это похоже на коренное изменение основного Не могли бы вы поподробнее рассказать об управлении транзакциями между компонентами когда работа ведется с одной базой данных?

Если я передаю строку подключения и соединение остается открытым, не ведет ли это к дополнительным издержкам?

Ответ Замечательный вопрос! Вместо краткого ответа я обсу дить созданное мной приложение-пример. После этого мы перейдем к воп росу об Публиковалось в Magazine/Русская 2002. № июнь). Прим. изд.

Доступ к из Начнем с создания Я разработал приложение пример, вставляющее от одной до четырех строк в таблицу Order Derails демонстрационной базы данных Приложение спроектировано так, что оно или фиксирует все операции вставки, или отменяет в слу чае ошибки. В приложении используются SQL Server и провайдер данных Почти то же самое можно сделать, используя провайдер OLE если СУБД транзакции.

Вместо чтобы полагаться образец кода для работы с транзакция предлагаемый в документации и поясняющий, как реализуются тран закции в я использую простой принцип распределения компо по уровням. Весь код, работающий с базой данных, находится в компонентов, а клиентским служит Windows-форма, в отдельный проект.

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

Создав неременную строки подключения, я создаю закрытые переменные для экземпляров SqlConnection и Transact потом.

В классе используется функция которую я показы вал в своей колонке за апрель 2002 г.

Она не участвует в транзакциях, а возвращает Для упрощения я использую ста тический SQL вместо хранимых процедур.

Теперь взглянем на участвующие в транзакциях, и еще на не сколько функций, которые в транзакциях не участвуют. OpenConnection создает новое SqlConnection и открывает его. Затем она начинает транзакцию в базе данных, вызывая BeginTransaction, и пере менной Transaction Current ссылку на транзакцию:

Public Sub = New О = End Sub Если вам нужно соединение и не требуется поддержка може те вызвать транзакциями между 38?

Public Sub = New End Sub Когда настает пора зафиксировать транзакцию, вызывается процедура:

Public Sub End Sub Для отката транзакции предназначена процедура:

Public Sub End Sub Закончив работу с его следует закрыть. Следующая проце дура закрывает соединение и удаляет ссылку на объект соединения:

Public Sub CloseConnection() If Is Nothing Exit Sub End If If = Then ConnectionCurrent = Nothing End If End Sub Итак, что нужно сделать, чтобы в рамках транзакции выполнить операцию вставки или модификации данных? Как раз для этого и предназначена функция on Query. Она создает новый экземпляр класса SqlCom затем присваивает свойству Connection текущее соединение (Con nectionCurrent), а свойству Transaction Ч текущую транзакцию (Tran sactionCurrent). Далее метод выполняет SQL-оператор, и издержки этого метода невелики, так как он не возвращает никаких дан ных (рис. 2).

Последняя функция класса Ч RunSQLScalar, которая выполняет SQL-опе ратор и возвращает единственное поле данных. Она удобна, если вам надо извлечь один блок данных, скажем, Unit Price для какого-либо товара.

При беглом просмотре класса видно, что он поддерживает информацию о состоянии. Вы должны создать его экземпляр, открыть соединение с тран закцией и выполнить код, который должен работать как часть транзакции.

Далее нужно зафиксировать или отменить транзакцию и закрыть соедине ние. Это не так сложно, поскольку вы можете создать экземпляр класса, 388 к из проделать работу и закрыть соединение в своем приложении. В моем при ложении-примере интерфейс на основе Win dows и просто создается экземпляр класса на время выполнения этого приложения.

Рис. 1.

Imports Public> = If Sub Public Function As String, Optional As String As DataSet As New Dim oOataAdapter As ' новый New _ sConnectionString) Заполняем набор данных DataAdapter oOataAdapter.

* Nothing ' функции Return oOataSet End Function.

Sub * New ' TransactionCurrent End Sub Public Sub ConnectionCurrent = New End см, след. стр.

Управление Рис, 1.

Sub End Sub Public Sub Sub Sub If Is Nothing Then Exit Sub End If If Nothing End If End Sub Public As String ' Указываем транзакции ' выполняемой локальной As New = Try cmd sSQt cmdLocal.

Catch exc As Exception "Error occurred & Finally End Try End Function Public Function RunSQLScalar(ByVal sSQL As As ' объект ' выполняемой локальной транзакции As SqlCommandO Dim As Boolean = True As String If Is Then bConnectionAlreadyOpen False <> Then bConnectionAlreadyOpen = False End If If bConnectionAlreadyOpen = False Then см. след. стр.

390 к данным из Рие.

False End If = ConnectionCurrent sSQL sTemp = Catch exc As Exception sTemp = "Error occurred & Finally If Not bConnectionAlreadyOpen Then ConnectionCurrent Nothing End If End Try Return End Function End>

Public Function sSQL As String) As String ' объект ' для выполняемой локальной Dim cmdLocal As New * ConnectionCurrent = Try = sSQL Catch exc As Exception Return "Error occurred & Finally End Try End Function На рис. З показан интерфейс Windows-формы. Он несложен. Вы выбира ете заказ из поля со списком вверху, затем кнопки со стрелками Управление транзакциями компонентами для добавления позиций (строк) заказа. В данном случае показан заказ с двумя позициями. В тестирования полям Quantity и Discount при своены 1 и, items Рис. 3. Форма для транзакций Заполнив строки, щелкните кнопку Ч ADO.NET добав ления новых записей в таблицу Order Details вашей базы данных.

Теперь посмотрим на саму форму. Поля со списками, Orders (cboOrders) и Products обеспечивают доступ к спискам заказов и това ров. Я поясню кое-какие тонкости, которые позволят сэкономить время.

Проектируя форму, я скрыл все элементы управления для ввода и включал их по мере необходимости. Для этого я присвоил свойству значение False и пытался устанавливать значение True всякий раз, когда включал строку Почему-то это постоянно вызывало ошибку в период выполнения. Тогда мне стало инте ресно, что будет, если поместить cboProducts в элемент управления Panel.

Я поместил на форму Panel (pnlProduct), в него Ч cboProducts и устано вил размер панели в соответствии с cboProducts;

после чего я указывал расположение и видимость панели, а не cboProducts. Это срабо тало. Почему Ч не знаю. Форма на этапе разработки показана на рис. 4.

Под полем со списком Orders расположено Ч cboProducts. Оно помещается первого текстового поля в строке (напри мер, txtProductName_l), когда пользователь вводит данные в эту строку.

Остальную часть интерфейса можно изучить, скачав исходный код ( /download.microsoft.com/download/msdnmagazine/code/May02/WXP/EN US/Basics0205.exe). Взглянем на код, имеющий дело с транзакциями на стороне клиента. Когда пользователь кнопку Ч ADO.NET для вставки позиций заказа, обрабатывается событие ADONet Click.

392 Доступ к из Рис. 4. Форма для транзакций на этапе разработки В первых трех строках обработчика этого события объявляются Dim sSQL As String Dim sStatus As String = Dim sOrderlD As String Затем вызывается метод Если соединения нет, ошибка не возникает, а если есть, оно закрывается:

Далее открывается соединение и начинается транзакция:

Следующие несколько строк кода говорят сами за себя: в них просто на страиваются элементы управления, проверяется, введено ли название то вара, и определяется идентификатор IblMessage.Text = If <> "" Then = If sOrderlD = Then IblMessage.Text = "You must select an order to add items to" Exit Sub End If Еще несколько строк кода вставляют позиции заказа в базу данных вызо вом ' Вставка 1-й sStatus = Единственное отличие последующих вызовов Ч sStatus (чтобы убедиться, что в этой строке нет сообщения об ошибке и что элемент уп не пуст). Если эти условия соблюдены, вызывает ся Вставка 2-й записи If sStatus = And <> sStatus = End If Вызовы функции для третьей и четвертой строк я опустил, так как они отличаются лишь что ссылаются на другие элементы управления.

Insert Detail в последний раз, вы должны освободить транзак цию. Если sStatus что-то содержит, значит, произошла ошибка, и транзак цию нужно откатить методом Сообщения об ошибках показываются элементом управления Освобождение и откат/фиксация транзакции If sStatus <> Then = "Rolled back transaction due to error & "on row & N - & sStatus Exit Sub End If И, наконец, если ошибок не было, вызывается метод чтобы выполнить Текст IblMessage изменяется, чтобы пока зать успешность записи в базу данных, и соединение закрывается.

= "Line items inserted ok" Функция InsertOrderDetail довольно проста. Вот ее заголовок:

Function As String, _ sProductID As String, As String, As String, ByVal sDiscount As String) As String 394 Доступ к из приложений Далее создаются две Dim As As String Затем формируется SQL-оператор с использованием параметров, передан ных функции:

sSQL = "INSERT INTO [Order " Quantity, Discount) sSOL & & & & _ & ft sSQL 4= & & & В блоке Try/Catch содержится вызов которая и выпол няет SQL-оператор. Заметьте: если slnsertStatus содержит любое непустое значение, генерируется исключение. Это позволяет перехватывать все ошибочные ситуации в блоке Catch:

Try = If slnsertStatus <> Then Throw New End If Catch exc As Exception Return End Try End Function Вот и все. Ничего особенного. Как видите, ADO.NET позволяет легко ис пользовать если ваша база данных их поддерживает.

Вторая часть вопроса относилась к эффективности. Конечно, если нение остается это может вызвать проблемы. Тем не менее, как показывает мой пример, ADO.NET дает возможность управлять циями, а сколько времени вы будете держать соединение открытым, ре шать вам. Кроме того, ADO.NET поддерживает пулы соединений, му, если вы используете одну и ту же строку подключения, открытие и закрытие соединений увеличивает издержки крайне незначительно.

Вопросы и комментарии (на английском языке) присылайте на адрес Кен Спенсер (Ken Spencer) работает в компании 32Х Tech ( разработкой ПО и обучением, а также предоставляет консалтинговые услуги по технологиям Microsoft.

Читайте во II томе АЛЬМАНАХА ПРОГРАММИСТА Х инфраструктура ASP.NET Х использование HTTP-конвейеров Х серверные элементы управления ASP.NET Х написание безопасного кода Х создание Web-сервисов Х разработка приложений электронной коммерции и других Web-приложений ASP.NET в продаже с сентября 2003 г.

приложения Х интернет-магазин издательства www.ITbook.ru Х крупные книжные магазины Москвы издательство компьютерной И (095;

тел./факс (095) 145-4519;

rusedn.ru серии Press видеоролики и вопросы и по Наши Вы можете Х в Компьютерная и книга 38, (095] 778- уп. 6, (095) 928- дом ул.

1095) 290- книги (095) гвардия ул. Большая 28, (095) 238- "Дом книги на Ленинградский 7S, 152- Дом книги на 13, стр. 1.

"Мир печати ул. 2-я 54.

Торговый дом книги "Москва уп. 8, (095) 229- Х в Санкт-Петербурга:

Дом книги, СПб Дом военной Невский Магазин Подписные Литейный 57, (812) 273- Магазин Техническая ул. 2, (812) 164-6565, Магазин Невский 312- Торговый Дом 567- Х в Екатеринбурге:

ул. 12, Х в Великом "Наука и ул Большая Санкт-Петербургская.

Дворец 2-й этаж Х в 000 тел : (3832) 36- Х в (Казахстан):

8-327-908-28-57, (3272) Х в Киеве 000 Издательство (+1038044) 269- книга на Петровке, (+1038044) 268- S Оперативная информация для профессионалов в журнале MSDN Magazine/Русская Журнал рубрики и ответы Ч и ответы, с по Web.

спецификации XML (XML имен и т. на аспекты с ASP и Доступ к Ч с и с использованием На переднем крае Ч тогда разработки Ч Джеффри Рихтер и и о и ТОНКОСТИ Ч интересующие в Отладка и оптимизация Ч и к задач :

популярностью этот обязан своему наполнению: читатель получает самую.

компонентов и создание свежую и актуальную информацию как эффективного программного ХХ Х :

от ведущих разработчиков корпорации и Microsoft, так и от известных специалистов в сфере разработки приложений.

код приемы, Глубокие и содержательные статьи оказывают неоценимую помощь профессиональному разработчику, регулярно использующему и ответы Ч и средства Microsoft."

Из статьи Ольги Тематические статьи Microsoft в СНГ (лMSDN и подробно проблемы спецвыпуск № 1, Оформить подписку Информационная журнала и приобрести журнал можно ~ в интернет-магазине и Pages:     | 1 |   ...   | 3 | 4 | 5 |    Книги, научные публикации