Delphi ado net - IT Справочник
Llscompany.ru

IT Справочник
11 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Delphi ado net

Работа с ADO в Delphi. Часть 1

Всем привет, и вот мой первый урок, думаю урок полезный, так как работа с базами данных в Delphi очень важно, а тем более Access на мой взгляд самая легкая база данных, с которой можно работать в Delphi. В этой статье я расскажу Вам как эту самую Базу данных Access подключить в Delphi, ну а в последующих статьях мы рассмотрим как добавлять информацию, редактировать, удалять и так далее, и Вы убедиться потом что ничего сложного в этом нету. Для начала запустим Delphi. Создадим новое приложение File-New-Application, думаю здесь объяснять долго ничего не надо. Что делаем далее, на нашу главную форму «ставим» следующие компоненты

  • TDBGrid
  • TDataSource
  • TADOConnection
  • TADOQuery

Итак теперь по компонентам:

TDBGrid находиться на вкладке DataControls, предназначен для отображения данных БД в нашей программе (приложении)

TDataSource находится на вкладке Data Access, предназначен для связи нашей сетки отображения данных, с самой БД

TADOConnection находится на вкладке ADO, предназначен для подключения нашей БД по определенному провайдеру

TADOQuery находится также на вкладке ADO, предназначен для получение нужных результатов из нашей БД.

Ну по компонентам немного прошлись, свойства я их не рассказываю, так как пока что не об этом, но дальше будет интереснее. Далее нам необходимо создать Базу данных в MS Access. А как же без нее, думаю как создать примитивную БД в MS Access труда не составит, я создам БД и таблицу с полями

  • ФИО — строковый тип данных (fio)
  • оценка — числовой тип данных (oz)

И назову ее Student, сохраним нашу БД в нужное место и продолжим дальше, ах да ну и заполните вашу таблицу какими-нибудь данными. А теперь мы «свяжим» все необходимые компоненты, которые находятся на нашей главной форме

TADOQuery в свойстве Connection я «связываю» с TADOConnection из выпадающего списка я выбираю имя данного компонента.

TDataSource в свойстве DataSet я «связываю» с TADOQuery из выпадающего списка я выбираю имя данного компонента

TDBGrid в свойстве DataSource я «связываю» с TDatasource из выпадающего списка я выбираю имя данного компонента.

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

Далее выделяем компонент TADOConnection и в свойстве LoginPromt ставим на False. Это делаем для того, чтобы при подключении к БД у нас не запрашивался пароль, дальше в свойстве ConnectionString нажимаем на кнопку с «…» и появляется окно следующего вида:

В данном окне нажимаем на кнопку «Build…» и появляется коно следующего вида:

В данном окне мы выбираем провайдера, а именно Microsoft Jet 4.0 OLE DB Provaider и нажимаем кнопку «Далее«.

В данном окне мы указываем путь к нашей БД и имя пользователя по умолчанию Admin. Если ваша БД находится в корневом каталоге с программой, то в данном поле достаточно указать ее имя с расширением, а если еще в подкаталоге, то указывается это примерно так BDmydb.mdb

Почти все закончили осталось только нажать кнопку «Ок» и в свойстве компонента TADOConnection — Mode выбрать из выпадающего списка cmShareDenyNone.

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

Что мы в этом коде делаем, обычный запрос к нашей таблице Student, как мы и называли ее. То есть мы запрашиваем у нее этим запросом все поля с данными и после этого просто активируем наш запрос, чтобы данные отобразились с помощью свойства Active

Исходники с базой данных скачать можно тут

В следующем уроке по базам данных мы поговорим как добавлять, редактировать, удалять и корректировать информацию в Delphi в БД MS Access

Технология ADO

Delphi site: daily Delphi-news, documentation, articles, review, interview, computer humor.

В Delphi версий 5,6 и 7 поддерживается технология ADO (ActiveX Data Objects — объекты данных, построенные как объекты ActiveX), которая усиленно развивается корпорацией Microsoft. На основе этой технологии созданы соответствующие компоненты-наборы TADOTable, TADOQuery, TADOStoredProc, повторяющие в функциональном отношении компоненты TTable, TQuery, TStoredProc, но не требующие развертывания и настройки BDE на клиентской машине.

Основные особенности использования технологии ADO не зависят от архитектуры БД: эта технология характерна не только для файл-серверных БД, но также ц для клиент-серверных и трехзвенных БД. Однако в этом уроке (и в книге вообще) мы не будем рассматривать особенности компонентов TADOStoredProc и TRDSConnect ion, предназначенных для поддержки соответственно клиент-серверной и трехзвенной архитектур, — если вас интересуют эти вопросы, обратитесь к документации и/или к встроенной справочной службе.

Основным достоинством технологии ADO является ее естественная ориентация на создание «облегченного» клиента. В рамках этой технологии на машине разработчика БД устанавливаются базовые объекты MS ADO и соответствующие компоненты Delphi (рис. 9.1), обеспечивающие использование технологии ADO (эти установки осуществляются автоматически при развертывании Delphi). На машине сервера данных (это может быть файловый сервер в рамках файл-серверной технологии или машина с сервером данных — в технологии клиент-сервер) устанавливается так называемый провайдер данных — некоторая надстройка над специальной технологией OLE DB, «понимающая» запросы объектов ADO и «умеющая» переводить эти запросы в нужные действия с данными. Взаимодействие компонентов ADO и провайдера осуществляется на основе универсальной для Windows технологии ActiveX, причем провайдер реализуется как СОМ-сервер, а ADO-компоненты — как СОМ-клиенты.

На машине сервера создается и размещается источник данных. В случае файл-серверных систем отдельные таблицы типа dBASE, FoxPro, Paradox и т. п. должны управляться соответствующим ODBC-драйвером, а в роли провайдера используется Microsoft OLE DB Provider for ODBC drivers. Если по каким-либо причинам не найден нужный драйвер, файл-серверные таблицы можно перенести в формат MS Access. На их основе создается единый файл, содержащий все необходимые таблицы, индексы, хранимые процедуры и прочие элементы БД. Такой файл управляется машиной баз данных Microsoft Jet 4.0 Database Engine, а в роли провайдера используется Microsoft Jet 4.0 OLE DB Provider.

Рис. 9.1. Реализация технологии ADO в Delphi

Если используется промышленный сервер данных Oracle или MS SQL Server, данные не нуждаются в какой-либо предварительной подготовке, а в роли провайдера используется соответственно Microsoft OLE DB Provider for Oracle или Microsoft OLE DB Provider for SQL Server. Нетрудно обнаружить и явный недостаток такой технологии: ADO не может использоваться, если для соответствующей структуры данных (в частности, для БД многих популярных серверов — InterBase, Informix, DB2 и пр.) не создан нужный провайдер или ODBC-драйвер.

На машине клиента располагаются связные компоненты TADOConnect ion и компоненты-наборы данных TADOTable, TADOQuery, TADOStoredProc, а также не показанные на рисунке компоненты-наборы TADODataSet и командные компоненты TADOCommand. Каждый из этих компонентов может связываться с провайдером данных либо с помощью связного компонента TADOConnection, либо минуя его и используя собственное свойство ConnectionString. Таким образом, компонент TADOConnection играет роль концентратора соединений с источником данных компонентов-наборов, и в этом смысле он подобен компоненту TDatabase в традиционной архитектуре с BDE.

Компоненты-наборы TADODataSet в функциональном плане повторяют свойства Delphi компонентов TClientDataSet технологии MIDAS. Командные компоненты TADOCommand предназначены для реализации запросов на языке определения данных (Data Definition Language, DDL), то есть для реализации SQL-запросов, которые не возвращают данные (запросы типа CREATE, DROP, UPDATE и т. п.). Специальный компонент RDSConnection (не показан на рисунке) создан для упрощения связи с MS Internet Explorer и при разработке интранет-приложений. ,

Компоненты-наборы с помощью компонентов-источников TDataSource и визуализирующих компонентов TDBGrid, TDBMemo, TDBEdit и т. п. обеспечивают необходимый интерфейс с пользователем программы.

ПРИМЕЧАНИЕ Ничто не дается бесплатно — эта старая истина во многом относится и к ADO. Ско-рость доступа к данным с помощью средств СОМ (а технология ActiveX, являющаяся краеугольным камнем ADO, целиком базируется на СОМ) в общем случае оказывается заметно ниже традиционного для Delphi механизма на основе BDE (как будет показано дальше, для некоторых типичных случаев скорость уменьшается в десятки и сотни раз).

Читать еще:  Как перенести слово безопасности

BDE против ADO в Delphi

Пожалуйста, обратите внимание на редактирование ниже для получения более подробной информации и возможного решения

Недавно мы модифицировали большое приложение Delphi, чтобы использовать ADO соединений и запросов вместо BDE соединений и запросов. После этого изменения производительность стала ужасной.

Я профилировал приложение, и узкое место, похоже, находится на фактическом вызове TADOQuery.Open . Другими словами, Я мало что могу сделать с точки зрения кода, чтобы улучшить это, кроме реструктуризации приложения, чтобы фактически использовать базу данных меньше.

Есть ли у кого-нибудь предложения о том, как улучшить производительность приложения ADO-connected Delphi? Я попробовал оба приведенных здесь предложения, но практически безрезультатно.

Чтобы дать представление о разнице в производительности, я провел сравнительный анализ одной и той же крупной операции:

Под BDE: 11 секунд

Под ADO: 73 секунды

Под ADO после изменений, упомянутых в этой статье: 72 секунды

Мы используем серверную часть Oracle в среде клиент-сервер. Каждая локальная машина поддерживает отдельное подключение к базе данных.

Для записи строка подключения выглядит следующим образом:

Чтобы ответить на вопросы, заданные зендаром:

Я использую Delphi 2007 на Windows Vista и XP.

Бэк-энд — это база данных Oracle 10g.

Как указано в строке подключения, мы используем драйвер OraOLEDB.

Версия MDAC на моем тестовом компьютере — это 6.0.

Редактировать:

Под BDE у нас было много кода, который выглядел примерно так:

Но мы обнаружили, что вызов Sql.Add на самом деле очень дорог под ADO, потому что событие QueryChanged срабатывает каждый раз, когда вы меняете CommandText . Так что замена вышеизложенного на это была MUCH быстрее:

А еще лучше, вы можете скопировать TADOQuery из ADODB.pas, переименовать его под новым именем и вырвать событие QueryChanged , которое, насколько я могу судить, вообще не делает ничего полезного. Затем используйте свою новую, модифицированную версию TADOQuery вместо родной.

3 Ответа

Я не знаю о Delphi 2007, но я сделал то же самое с Delphi 7 и Oracle 8.

Вот что я сделал:

  • Установить TAdoDataSet.CursorLocation в соответствии с запросом:
    • clUseClient если запрос извлекает записи для GUI и запрос относительно «simple»-нет группировки или суммы
    • clUseServer если у запроса есть какая-то агрегация (сумма, группировка, подсчет)
  • Установить TAdoDataSet.CursorType в соответствии с запросом:
    • ctForwardOnly для отчетов, где вам не нужно прокручивать назад набор данных-работает только с clUseServer
    • ctStatic вместо GUI. Это единственный режим, который работает с clUseClient
  • Установить TAdoDataSet.LockType в соответствии с запросом:
    • ltReadOnly для каждого набора данных, который не используется для редактирования (таблицы, отчеты)
    • ltOptimistic когда записи публикуются в базу данных сразу после изменения (например, пользователь редактирует данные в форме)
    • ltBatchOptimistic при изменении большого количества записей. Это относится к ситуациям, когда вы получаете несколько записей, затем выполняете некоторую обработку на них, а затем отправляете обновления в базу данных в пакетном режиме. Это лучше всего работает в сочетании с clUseClient и ctStatic.
  • По моему опыту, Microsoft OLEDB provider for Oracle работал лучше, чем Oracle OleDb provider. Вы должны это проверить.
    Редактировать: проверить комментарий Фабрисио про возможные проблемы клякса.
  • Заменить TAdoQUery на TAdoDataSet . TAdoQuery был создан для преобразования приложений из BDE в ADO, но Borland / Codegear recomendation должна была использовать TAdoDataSet
  • Перепроверьте строку подключения Oracle, чтобы убедиться, что у вас нет задержки в сети. Как долго длится подключение к Oracle? Сколько времени составляет TnsPing?

я нашел проблемы с производительностью с ADOExpress лет назад:

Примечание: до того, как ADO стал стандартной частью Delphi, Borland продавал его как аддон под названием ADOExpress . Это были просто объектные оболочки вокруг объектов Microsoft ActiveX Data Objects (ADO) COM.

я проверил три сценария

  • использование ADO напрямую (т. е. непосредственно объектов Microsoft COM)
  • использование ADOExpress (объектные оболочки Борланда вокруг ADO)
  • указание .DisableControls на TADOQuery перед вызовом Open

я открыл для себя

  • используйте Query.DisableControls , чтобы сделать каждый вызов .Next в 50 раз быстрее
  • используйте Query.Recordset.Fields.Items[‘columnName’].Value вместо Query.FieldByName(‘columnName’) , чтобы ускорить поиск каждого значения 2.7x

использование TADODataSet (стихи TADOQuery ) не имеет никакого значения

Примечание: эти значения предназначены для циклического перебора 20 881 строк и поиска значений 21 столбца.

Базовый Плохой Код:

Используйте DisableControls, чтобы сделать цикл 5000% быстрее :

Используйте коллекцию полей, чтобы ускорить поиск значений 270% :

Поскольку это достаточно распространенная проблема, мы создали вспомогательный метод для решения этой проблемы:

Для лучшей производительности следует взглянуть на наш открытый исходный код прямого доступа к Oracle .

Если вы обрабатываете много TQuery, не используя компоненты DB, у нас есть специальный псевдокласс для использования прямого соединения OCI, как такового:

И я добавил некоторый уникальный доступ через вариант поздней привязки, чтобы написать прямой код как таковой:

Обратите внимание, что все поставщики OleDB глючат для обработки BLOBs: версия Microsoft просто не обрабатывает их, а версия Oracle случайным образом возвращает null для 1/4 строк .

В реальной базе данных я обнаружил, что наши прямые OCI классы работают в 2-5 раз быстрее, чем OleDB провайдер, без необходимости установки этого провайдера. Вы даже можете использовать мгновенный клиент Oracle, предоставляемый Oracle, который позволяет запускать ваши приложения без установки стандартного (огромного) клиента Oracle или наличия ORACLE_HOME. Просто доставьте файлы dll в тот же каталог, что и ваше приложение, и оно будет работать.

Похожие вопросы:

Мое приложение использует TDbChart и ADO. Мне было интересно, для deployment, мне нужно включить BDE файлов тоже? Знаете ли вы другие инструменты построения графиков, которые можно использовать с.

В чем разница между ado и bde?

Можно ли скачать BDE? У меня есть старое приложение delphi для поддержки, а у клиента-новый компьютер. Мне нужно скопировать EXE поперек и установить BDE на эту машину. Спасибо

у нас есть приложение некоторого размера (около 1 мл), которое было запущено еще в те дни, когда BDE только собирался быть устаревшим. В настоящее время мы используем его только для подключения к.

У нас есть старое приложение, которое читает в текстовых файлах SQL и отправляет их в Sybase ASE 12.51. Наше устаревшее приложение было написано в Delphi 5 и использует компонент BDE TQuery для.

В настоящее время я использую компоненты BDE для подключения к базе данных в версии Delphi 5 professional. Моя проблема заключается в том, что BDE компонентам нужен администратор BDE для запуска.

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

Мы переносим Delphi 7 приложений в Delphi XE. Мы заменяем компонент базы данных BDE на ADO. В приложении Delphi 7 мы активно использовали компонент TwwQuery (Info Power). Хотя TwwQuery.

У меня есть приложение в моей компании. Я хочу преобразовать его из BDE в соединение ADO. Я искал почти везде, я не нашел никакого хорошего ответа. Цель такова Преобразуйте это соединение BDE в.

В настоящее время у меня есть старый проект Delphi, использующий BDE для подключения к Paradox. Мы хотим выяснить, можно ли использовать ADO для замены BDE, но по-прежнему использовать парадокс для.

Асинхронная загрузка данных с помощью ADO в Delphi

Автор: Alex. Опубликовано в Программирование 05 Февраль 2016 . просмотров: 11047

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

Создание проекта

На самом деле, в ADO уже всё готово для асинхронной загрузки данных, нужно лишь выставить определённые опции и обработать необходимые события. Но в Delphi всё оказалось не настолько просто. Для отображения данных в Delphi используется таблица TDBGrid унаследованная от TCustomDBGrid (или многочисленные сторонние разработки, тоже унаследованные от TCustomDBGrid), ссылающаяся на объект TDataSource, который, в свою очередь, ссылается на TDataSet. И в случае работы с ADO вы должны использовать обёртки TADOStoredProc, TADOQuery, TADOTable и TADODataSet, которые унаследованы от объекта TDataSet. Как раз эти обёртки и не дают в полную силу пользоваться асинхронной загрузкой данных. Чтобы понять, что работает и что не работает при использовании этих обёрток, сделаем простой пример с их использованием.

Все эксперименты в статье я буду делать, используя локальную СУБД MSSQL 2008 и Delphi 10 Seattle. Для экспериментов я создал простую таблицу и заполнил её случайным набором данных. Вот скрипт, который я использовал:

Теперь в Delphi сделаем новый проект с VCL-формой (пункт меню File -> New -> VCL Forms Application — Delphi), на форму положим таблицу TDBGrid и две кнопки TButton. Одна кнопка будет для начала загрузки, а вторая для отмены загрузки. Имена кнопкам я дам соответствующие – ButtonLoad и ButtonCancel. Все остальные имена оставлю без изменений. Кнопку отмены по умолчанию сделаем неактивной, Enabled выставим в False. Зададим, также, заголовок формы и текст на кнопках. Ещё я добавлю компонент TProgressBar, который будет нам показывать идёт ли процесс загрузки или нет и компонент TLabel для отображения количества загруженных записей. Свойство Style прогресс-бара выставим в pbstMarquee, а Visible – в False.

После того как с визуальной частью формы закончено, положим на форму компоненты TDataSource, TADOQuery и TADOConnection. Теперь нужно связать таблицу TDBGrid (у нас она получила имя DBGrid1) с источником данных TDataSource (у нас он с именем DataSource1), источник данных – с запросом TADOQuery (у нас он с именем ADOQuery1), а запрос – с соединением TADOConnection (у нас оно с именем ADOConnection1). Т.е. получается вот такая связь: DBGrid1 -> DataSource1 -> ADOQuery1 -> ADOConnection1. Для этого устанавливаем у таблицы свойство DataSource равным DataSource1, свойство источника данных DataSet равным ADOQuery1, а свойство запроса Connection равным ADOConnection1.

Теперь нужно задать свойства соединения в свойстве ConnectionString объекта ADOConnection1. У меня это будет следующая строка:

Здесь я сразу указал имя пользователя и пароль, поэтому можно отключить стандартное окно запроса имени пользователя и пароля выставив свойству LoginPrompt компонента ADOConnection1 значение False.

Теперь придумаем такой запрос, который будет долго выполняться, и запишем его в свойство SQL компонента ADOQuery1. Заодно будем засекать, сколько будут загружаться данные для каждого из вариантов загрузки. Я сделал вот такой запрос:

У меня этот запрос в SQL Management Stodio выполнился за 1 минуту и 9 секунд.

Простой синхронный запрос данных в Delphi с помощью ADO

Для начала сделаем простой синхронный запрос данных. Выполнять запрос будем по событию OnClick кнопки ButtonLoad. Вот такой будет код для выполнения запроса:

Запустите приложение, нажмите на кнопку «Загрузить». Записи открылись даже быстрее, чем в SQL Server Management Studio, всего за 26 секунд, но при просмотре происходят подтормаживания, причём, чем ближе к концу таблицы, тем они больше. Интересный результат.

Простой асинхронный запрос данных в Delphi с помощью ADO

Теперь попробуем выполнить этот запрос асинхронно. Для этого установите у свойства ExecuteOptions компонента ADOQuery1 флажок eoAcyncExecute в True. А чтобы соединение с СУБД тоже происходило асинхронно, установите свойству ConnecOptions значение coAsyncConnect. Количество записей теперь нужно будет показывать только после того как запрос выполнится. Об этом можно узнать по событию AfterOpen компонента ADOQuery1. Ошибки можно отловить по событию OnExecuteComplete компонента ADOConnection1. Пока запрос обрабатывается, будем показывать прогресс-бар, делать активной кнопку «Отмена», а кнопку «Загрузка» — неактивной. Отменять выполняющийся запрос будем как положено в ADO – вызовом функции Cancel. Вот как будет выглядеть код:

Запустите форму и нажмите на кнопку «Загрузить». После этого кнопки «Загрузка» и «Отмена» поменяют активность, появится прогресс-баз и начнётся загрузка, см. картинку ниже. Данные отобразятся в таблице только после загрузки. Время загрузки здесь получилось такое же – 26 секунд, и так же при просмотре происходят подтормаживания.

Отмена простого асинхронного запроса данных в Delphi с помощью ADO

Загрузка из примера выше работает прекрасно, пока вы не нажмёте на кнопку «Отмена». Здесь есть 2 проблемы:

    1. Когда данные уже начали загружаться на клиента, отмена не срабатывает. Вместо отмены программа зависает на строчке «ADOQuery1.Recordset.Cancel;», пока все данные полностью не загрузятся.
    2. После вызова функции «ADOQuery1.Recordset.Cancel;» (если конечно запрос реально отменился, см. п. 1), повторно выполнить запрос не получится, т.к. вызов метода «ADOQuery1.Open;» не произведёт никаких действий. Это происходит из-за того, что компонент ADOQuery1 остаётся закрытым (Active = False), но в то же время его статус показывает, что запрос открывается (State = dsOpening). Это наглядно показывает на то, что обёртки VCL над ADO не поддерживают отмену.

Первую проблему можно попробовать обойти одним из трёх способов:

    1. Поменять драйвер, если другой драйвер у вас есть. Но, может случиться так, что нужного вам драйвера не существует или БД не поддерживает отмену запросов.
    2. Использовать серверный курсор (для этого нужно выставить у компонента ADOQuery1 свойство CursorLocation в clUseServer). Но с серверным курсором вы не сможете узнать количество записей и для отображения данных нужно постоянное подключение к СУБД. Поэтому, чтобы работать с данными на клиенте, вам придётся скопировать их в оперативную память (например, в компонент TClientDataSet) или в локальную базу данных, если объём данных очень большой. А чтение всех данных из серверного курсора происходит медленно.
    3. Сделать фиктивную остановку загрузки. Т.е. показывать пользователю, что запрос отменён, а на самом деле давать запросу выполниться до конца и только после этого его удалять. Можно, конечно удалять компоненты TADOQuery во время загрузки (это возможно, если выставить флаг eoAsyncFetchNonBlocking в True), но загрузка данных объектами ADO при этом не остановится, она будет продолжаться. Это видно даже в диспетчере задач. К тому же при удалении компонентов TADOQuery во время загрузки периодически происходит ошибка «access violation at 0x1cbaf811: read of address 0x00000000» где-то в недрах ADO.

Вторую проблему никак не обойти. Здесь есть только одно решение – после каждой отмены (или вообще каждый раз), для каждого нового запроса создавать новый компонент TADOQuery, а существующий компонент удалять сразу или позже при завершении работы приложения.

Учитывая возникшие с отменой проблемы, код формы сильно поменяется. Я уберу с формы компоненты ADOQuery1 и ADOConnection1 и буду создавать их при каждой загрузке данных. Ниже я приведу два примера и опишу их минусы.

Вот первый пример. Здесь я использую серверный курсор для получения данных. Для отображения я копирую данные в компонент TClientDataSet. Отмена загрузки здесь работает превосходно. Но есть другие проблемы, о которых будет написано ниже.

В этом примере копирование работает крайне медленно. Судите сами: примерно половина запрошенных данных копировалась аж 23 минуты и 17 секунд. Замеры с помощью профайлера показали, что очень медленно работает перемещение по данным с помощью серверного курсора (строка кода «query.Next;») — 20 минут и 19 секунд. На втором месте оказалось копирование полей (строка кода «clientDataSet.CopyFields(query);») – 2 минуты и 9 секунд. В довершение ко всему, примерно посередине загрузки произошла ошибка при копировании 5218000-ой записи: «Exception class EDBClient with message ‘Insufficient memory for this operation.’.». Так что, в компонент TClientDataSet у вас никак не удастся записать 10000000 записей.

Поэтому, если вам нужно загрузить на компьютер пользователя большой объём данных, нужно искать другой способ. Приведённый пример загрузки и хранения данных в оперативной памяти подойдёт только для небольших объёмов.

Асинхронная пошаговая загрузка данных в Delphi с помощью ADO

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

Есть два варианта, как это можно сделать. Первый вариант – это небольшое изменение предыдущего примера, где загрузка происходит из серверного курсора. Смысл изменения состоит в том, что мы должны сразу привязать таблицу к компоненту TClientDataSet и по мере наполнения компонента TClientDataSet, таблица сразу будет отображать новые записи. Здесь поменяются только методы AfterOpen и WndMethod:

Второй вариант – это установка флага eoAsyncFetchNonBlocking в True у компонента TADOQuery и постепенная загрузка данных в событии OnFetchProgress. Этот способ работает в 10 раз быстрее, чем предыдущий. Правда, здесь я столкнулся с одной проблемой: при выборке данных по событию OnFetchProgress невозможно установить курсор на первую запись (вызовы методов First или Prior не помогают) и, в результате, у нас происходит загрузка всех записей, кроме первой. Чтобы это избежать, будем загружать данные напрямую с помощью ADO. Пример поменяется сильно, поэтому я приведу здесь полный текст:

Асинхронная пошаговая загрузка нескольких наборов данных в Delphi с помощью ADO

Если вам требуется асинхронно загрузить несколько наборов данных, так же как это сделано в предыдущем примере, то вы можете даже не пытаться это делать. Дело в том, что когда вы будете переходить к следующему набору данных с помощью «query.Recordset := query.NextRecordset(recordsAffected);», в этот момент компонент TADOQuery закрывает курсор и больше вы ничего не получите. Да, это прекрасно работает при синхронных запросах, но только не по событию OnFetchProgress. Пример с чтением из серверного курсора тоже работать не будет.

Но если вы всё-таки захотите асинхронно пошагово загружать данные с несколькими наборами, то используйте ADO напрямую. Кода, конечно, будет намного больше, но в этом случае всё будет работать. В статье я не буду приводить таких примеров, т.к. это будет довольно объёмный код. Но если вы заинтересованы, пишите об этом в комментариях.

BDE против ADO в Delphi

обратите внимание на редактирование ниже для получения дополнительной информации и возможного решения

недавно мы изменили большое приложение Delphi для использования соединений и запросов ADO вместо соединений и запросов BDE. С тех пор производительность стала ужасной.

я профилировал приложение, и узкое место, похоже, находится на фактическом вызове TADOQuery.Open . Другими словами, с точки зрения кода я мало что могу сделать для улучшения это, кроме реструктуризации приложения, чтобы фактически использовать базу данных меньше.

есть ли у кого-нибудь предложения о том, как улучшить производительность приложения Delphi, подключенного к ADO? Я пробовал оба читать здесь, практически без воздействия.

чтобы дать представление о разнице в производительности, я сравнил ту же большую операцию:

под BDE: 11 секунды!—13—>

под ADO: 73 секунды

по Адо после изменения ссылки на статью: 72 секунды

мы используем серверную часть Oracle в среде клиент-сервер. Локальные компьютеры поддерживают отдельное подключение к базе данных.

для записи, строка подключения выглядит так:

ответить на вопросы zendar:

Я использую Delphi 2007 В Windows Vista и XP.

задняя часть является базой данных Oracle 10g.

как указано в строке подключения, мы используем драйвер OraOLEDB.

версия MDAC на моей тестовой машине-6.0.

Edit:

под BDE у нас было много кода, который выглядел так:

но мы обнаружили, что вызов Sql.Add на самом деле очень дорогой при ADO, потому что QueryChanged событие запускается каждый раз, когда вы изменяете CommandText . Таким образом, замена вышеизложенного на это была намного быстрее:

а еще лучше, вы можете скопировать TADOQuery из ADODB.pas, переименуйте его под новым именем и вырвите QueryChanged событие, которое, насколько я могу судить, не делая ничего полезного вообще. Затем используйте новую, модифицированную версию TADOQuery вместо родной.

3 ответов

Я не знаю о Delphi 2007, но я сделал то же самое с Delphi 7 и Oracle 8.

вот что я сделал:

  • Set TAdoDataSet.CursorLocation согласно запросу:
    • clUseClient если запрос извлекает записи для GUI, а запрос относительно «прост» — нет группировки или суммы
    • clUseServer если запрос имеет некоторую агрегацию (сумму, группировку, подсчет)
  • Set TAdoDataSet.CursorType согласно запросу:
    • ctForwardOnly для отчетов, где вам не нужно прокручивать через набор данных — работает только с clUseServer
    • ctStatic для GUI. Это только режим, который работает с clUseClient
  • установить TAdoDataSet.LockType согласно запросу:
    • ltReadOnly для каждого набора данных, который не используется для редактирования (таблицы, отчеты)
    • ltOptimistic когда записи отправляются в базу данных сразу после изменения (например, пользователь редактирует данные в форме)
    • ltBatchOptimistic при изменении большого количества записей. Это для ситуаций, когда вы получаете количество записей, затем выполнить некоторую обработку на них, а затем отправить обновления в базу данных в пакетном режиме. Это работает лучше всего в сочетании с clUseClient и ctStatic.
  • по моему опыту, поставщик Microsoft OLEDB для Oracle работал лучше, чем поставщик Oracle OleDb. Ты должен это проверить.
    Edit: Проверьте комментарий Фабрицио о возможных проблемах blob.
  • заменить TAdoQUery С TAdoDataSet. TAdoQuery был создан для преобразования приложений из BDE в ADO, но Borland/Codegear recomendation должен был использовать TAdoDataSet
  • перепроверьте строку подключения Oracle, чтобы убедиться, что у вас нет задержки сети. Как долго длится подключение к Oracle? Как долго TnsPing?

я нашел проблемы с производительностью с ADOExpress лет назад:

Примечание:ADOExpress. Это были просто обертки предметов вокруг COM-объекты объектов данных ActiveX (ADO) корпорации Майкрософт.

я проверил три сценария

  • используя ADO напрямую (т. е. COM-объекты Microsoft напрямую)
  • использование ADOExpress (обертки объектов Borland вокруг ADO)
  • задание .DisableControls на TADOQuery перед вызовом Open
  • использовать Query.DisableControls сделать каждый вызов .Next 50x быстрее
  • использовать Query.Recordset.Fields.Items[‘columnName’].Value , а не Query.FieldByName(‘columnName’) чтобы сделать каждый поиск значения 2.7 x быстрее

используя TADODataSet (стихи TADOQuery ) не имеет значения

Примечание: эти значения предназначены для цикла 20,881 строк и поиска значений 21 столбца.

Базовый Плохой Код:

используйте DisableControls для создания цикла 5000% быстрее!—29—>:

используйте коллекцию полей, чтобы сделать поиск значений на 270% быстрее:

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

для лучшей производительности, следует взглянуть на наш С открытым исходным кодом прямой доступ к Oracle.

Если вы обрабатываете много TQuery, без использования компонентов DB, у нас есть выделенный псевдо-класс для использования прямого OCI-соединения, как такового:

и я добавил уникальный доступ через вариант поздней привязки, чтобы написать прямой код как таковой:

обратите внимание, что все поставщики OleDB глючат для обработки BLOBs: версия Microsoft просто не обрабатывайте их, и версия Oracle будет случайным образом возвращает null для 1/4 строк.

в реальной базе данных я обнаружил, что наши прямые классы OCI в 2-5 раз быстрее, чем поставщик OleDB, без необходимости устанавливать этого поставщика. Вы даже можете использовать Oracle Instant Client предоставляется Oracle, который позволяет запускать приложения без установки стандартного (огромного) клиента Oracle или наличия ORACLE_HOME. Просто доставьте файлы dll в том же каталоге, что и ваше приложение, и он будет работать.

Ссылка на основную публикацию
ВсеИнструменты 220 Вольт
Adblock
detector