Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Работа с Firebird и InterBase в Delphi.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
190.72 Кб
Скачать

Работа с Firebird и InterBase в Delphi. Часть 1.

Введение. Доступ к InterBase и Firebird из Delphi

В Delphi cуществует несколько способов работы с InterBase и Firebird. Мне известны, как минимум, 3 способа организации доступа к данным через IBProvider:

  • dbGo (ADO Express) компоненты, работающие через библиотеку ADO.

  • прямой доступ к COM-интерфейсам ADO, минуя компоненты dbGo.

  • прямой доступ к COM-интерфейсам OLE DB при помощи сторонних VCL-компонент (OLE DB Direct/OLE DB Express).

Компоненты dbGo

dbGo — это VCL-компоненты от Borland, позволяющие работать с библиотекой ADO из Delphi и C++ Builder привычным для этих средств разработки способом. До Delphi 6 компоненты назывались ADOExpress.

Внешний вид панели компонентов dbGo в Delphi (RAD Studio 2007):

Состав dbGo-компонентов:

  • Компонент TADOConnection — подключение к базе данных.

  • Компонент TADODataSet — базовый набор данных. TADODataSet позволяет загружать данные таблиц, хранимых процедур и произвольных SQL запросов и передавать изменения обратно в БД. Важным условием является то, что выражение указанное в CommandText, обязательно должно возвращать набор данных. TADODataSet соответствует объекту ADODB.Recordset.

  • Компонент TADOTable является упрощенными вариантом TADODataSet. Он позволяет загружать в память целые таблицы.

  • Компоненты TADOQuery и TADOStoredProc предназначены для выполнения произвольных SQL-запросов и хранимых процедур.

  • Компонент TADOCommand соответствуют объеку ADODB.Command. Фактически объединяет в себе возможности трех компонентов: TADOTable, TADOQuery, TADOStoredProc.

Создание подключения TADOConnection

Компонент TADOConnection осуществляет соединение с хранилищем данных. TADOConnection похож на компонент TSQLConnection. Разница между ними в том, что при работе с TSQLConnection параметры соединения устанавливались с помощью свойств ConnectionNameDriverName и Params. В TADOConnection все параметры подключения задаются через свойство ConnectionString. Кроме того в качестве строки подключения в TADOConnection может быть указано имя файла с параметрами подключения.

Для хранения параметров подключения в Windows существует специальный тип файлов Microsoft Data Link — это файл с расширением udl. С этим расширением ассоциирован универсальный редактор подключений. IBProvider поддерживает свои собственные табы, которые предоставляют удобный интерфейс для формирования параметров соединения. Для того чтобы использовать udl файл в своем приложении выполните следующие шаги:

  • Создайте пустой файл с расширением .udl

  • Откройте файл (Enter), появится связанный с данным расширением диалог для настройки подключения

  • В списке OleDb провайдеров выберете IBProvider v3:

  • Установите параметры подключения к БД и нажмите кнопку «Проверить подключение». На рисунке заданы следующие параметры:

    • Интегрированная аутентификация Firebird 2.1;

    • Источник — тестовая БД localhost:employee.fdb. Подключение определено без пути, т.к. БД прописана в файле aliases.conf;

    • Режим автоматического управления транзакциями: Включен;

    • Кодировка: WIN1251 или другая кодировка, поддерживаемая Firebird или InterBase;

СОВЕТ Всегда включайте в параметр Location сетевое имя компьютера на котором установлен сервер Firebird или InterBase. Для локального подключения используйте localhost. Это позволит обеспечить совместимость.

Теперь добавьте на форму компонент TADOConnection. Задайте свойство: Login Promt=false и установите в качестве строки подключения ConnectionString созданный ранеее файл подключения udl:

Подробная информация о свойствах инициализации IBProvider.

Отображение данных через TADOTable

Компонент TADOTable позволяет загружать данные одной таблицы.

  • Найстройте объект TADOConnection:

    • Connected = true;

    • Login Promt = false;

  • Добавьте на форму объект TADOTable и настройте его следующим образом:

    • Connection = ADOConnection1;

    • TableName = имя таблицы из employee.fdb (CUSTOMER, EMPLOYEE, PROJECT и т.п.);

    • Active=true;

  • Добавьте компонент TDataSource с вкладки Data Access. Настройки:

    • DataSet = TADOTable1;

  • Добавьте компонент TDBGrid с вкладки Data Controls. Настройки:

    • DataSource = DataSource1;

В результате DBGrid отобразит данных той таблицы, которая была выбрана в объекте TADOTable:

Компонент TADODataSet

Компонент TADODataSet — это надстройка над объектом ADODB.Recordset. В отличии от TADOTable, TADODataSet может загружать не только таблицы, но и множества, возвращаемые хранимыми процедурами или SQL-запросами.

Перед началом работы с TADODataSet установите свойство Connection = ADOConnection1. Альтернативный вариант — эта указать строку подключения в свойстве ConnectionString. Но я настоятельно рекомендую для хранения подключения использовать отдельный объект TADOConnection.

В свойстве CommandText укажите текст команды для загрузки данных. Текстом команды могут являться:

  • SQL — запрос. (Примеры: «SELECT * FROM EMPLOYEE», «EXEC ALL_LANGS» и т.д.). При этом свойство CommandType=cmdText.

  • Имя таблицы. (Примеры: «EMPLOYEE», «CUSTOMER», «PROJECT»). CommandType=cmdTableDirect.

  • Имя хранимой процедуры. (пример: «ALL_LANGS», «SHOW_LANGS»). CommandType=cmdStoredProc.

Команда в CommandText должна возвращать набор данных. К примеру, в тексте нельзя использовать INSERT, DELETE или UPDATE, а так же указывать хранимые процедуры, которые не возвращают набор данных (Recordset).

Перейдем к практическому примеру демонстрирующему возможности Delphi при работе c Firebird/InterBase:

  • Создадим простейший редактор служащих на основе TADODataSet.

  • Перемещаться по записям будем при помощи компонента TDBNavigator.

  • Список служащих отобразим в TDBGrid.

  • Для редактирования деталей воспользуемся контейнером TDBCtrlGrid в который поместим TDBLabelTDBTextTDBComboBox.

Законченный пример показан на картинке:

Далее я приведу последовательность действий для воспроизведения примера саммостоятельно:

  • Добавьте на форму и настройте компонент TADOConnection.

  • Добавьте компонент TADODataSet и настройте его следующим образом:

    • CommandText = «select EMP_NO, FIRST_NAME, LAST_NAME, FULL_NAME, JOB_COUNTRY, DEPT_NO from EMPLOYEE»;

    • CommandType = cmdText;

    • Active = true;

  • Добавьте компонент TDataSource с вкладки Data Access:

    • Установите свойство DataSet = ADODataSet1;

  • Добавьте на форму 2 компонента c вкладки Data Controls: TDBNavigator и TDBCtrlGrid:

    • Каждому установите свойство DataSource = DataSource1;

    • У TDBCtrlGrid установите RowСount = 1;

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

TDBLabel — нередактируемое поле. При помощи этого компонента будем отображать колонку FULL_NAME.

Для редактирования полей FIRST_NAME, LAST_NAME добавим на форму 2 компонента TDBText, у которых установим свойство DataField.

Поле JOB_COUNTRY связано внешним ключом с таблицей COUNTRY. Для редактивания этого поля используем выпадающий список TDBComboBox содержащий коды стран. После установки поля DataField = JOB_COUNTRY, необходимо заполнить список данными из таблицы COUNTRY.

Кроме описанных в примере, на вкладке Data Controls расположены компоненты для редактирования изображений (TDBImage), многострочного текста (TDBMemo), отображения списков и т.д.

Передача изменений в БД — технология обновляемых множеств

IBProvider поддерживает замечательную возможность OLE DB — технологию обновляемых множеств. Благодаря этой технологии, в приведенном примере не пришлось прописывать в коде логику передачи изменений обратно в БД. Все изменения передавались автоматически через обновляемые множества. На данный момент технологию обновляемых множеств поддерживает только IBProvider v2. Пожалуйста учитывайте это при выборе провайдера для подключения.

Клиентские и серверные курсоры

Для перемещения по записям IBProvider использует курсоры. Они бывают серверные и клиентские.

Клиентский курсор — хранится на стороне клиента. После выполнения запроса всё результирующее множество загружается в оперативную память или swap-файл драйвера. Это может вызывать задержки при передаче больших объемов данных, особенно по сети. По умолчанию в dbGo используется именно клиентский тип курсора. Это дает преимущество в быстродействии на небольших объемах данных. С клиентскими курсорами могут работать все три провайдера из состава IBPRovider Professional Edition.

Серверный курсор используется при работе с большими наборами данных, которые невыгодно пересылать клиенту целиком. В результате сразу после выполнения запроса клиенту возвращается курсор, а данные считываются по мере необходимости. Кроме того реализация IBProvider, позволяет считывать BLOB-поля по мере обращения к ним, а не при получении всей записи. Это так же повышает производительность, в случае если в одной записи содержится несколько BLOB-колонок с большими данными. В текущей реализации серверный курсор можно использовать только с IBProvider v1, т.к. только он поддерживает 4-х байтные закладки, которые используются в dbGo для работы в режиме серверных курсоров. Более новые версии IBProvider используют уже 8-байтные закладки.

За тип курсора отвечает свойство CursorLocation. Оно может принимать значения clUseServer и clUseClient.

Какой провайдер выбрать?

В состав IBProvider Professional входят три OLE DB провайдера, которые предоставляют разработчику различные возможности.

IBProvider v1 — на данный момент единственный провайдер, позволяющий работать с dbGo компонентами в режиме серверных курсоров. Это связанно с ограниченным размером закладок в dbGo = 4 байта. Мы уже запланировали сделать IBProvider v3 совместимым с серверными курсорами dbGo в Delphi и C++ Builder. Как только это будет реализовано, IBProvider v1 станет историей. Для использования провайдера, укажите в строке подключения Provider=LCPI.IBProvider.1

IBProvider v2 поддерживает технологию обновляемых множеств. Благодаря им появляется возможность передавать изменения обратно в БД без явного указания текстов команд на вставку/удаление/обновление. Провайдер самостоятельно генерирует SQL-команды на основании select-выражений. Пример использования этой технологии я привел выше. Для использования провайдера, укажите в строке подключения Provider=LCPI.IBProvider.2. В наших ближайших планах реализовать поддержку обновляемых множеств в IBProvider v3.

IBProvider v3 самый современный и производительный из всех провайдеров. Он обладает уникальным набором технологий, поддерживает все кодовые страницы, специальные возможности последних версий серверов Firebird и InterBase, 64-битные операционные системы и множество других полезных функций. Если вы не планируете использовать обновляемые множества или серверные курсоры однозначно выбирайте IBProvider v3. Для этого укажите в строке подключения Provider=LCPI.IBProvider.3 или Provider=LCPI.IBProvider.

Если вам необходимо использовать возможности всех трех драйверов в одном Delphi-приложении, то в качестве временного решения, рекомендую использовать три одинаковых подключения к БД с разными драйверами. К примеру, все основные операции пропускать через IBProvider v3, обновляемые множества через IBProvider v2, а кешировать данные через серверные курсоры с IBProvider v1. После того как обновляемые множества и поддержка серверных курсоров dbGo будет доступна в IBProvider v3 можно будет оставить только одно подключение.

Компонент TADOQuery

Компонент TADOQuery предназначен для выполнения SQL-команд. Его можно рассматривать, как аналог компонента TSQLQuery из dbExpress. Связь с базой данных устанавливается через свойства Connection или ConnectionString. Текст запроса записывается в свойство SQL. Если запрос возвращает набор данных, следует использовать метод Open() или свойство Active=true. Если запрос не должен возвращать набор данных, то его необходимо выполнять с помощью метода ExecSQL. ExecSQL возвращает число записей, которые были обработаны во время выполнения запроса. Это же значение содержится в свойстве RowsAffected.

SQL-запросы с параметрами

Запросы могут быть параметризованными. При помощи параметров команды можно задавать условия и передавать данные серверу БД. Существуют два вида параметров: Именованные и позиционные. По умолчанию именованные параметры в IBProvider задаются через двоеточие (:), a позиционные через знак вопроса (?).

Для демонстрации работы компонента TADOQuery напишем пример, в котором рассмотрим три варианта его применения:

  • Выполнение запросов с именованными параметрами. ExecSQL и RowsAffected.

  • Выполнение запросов с позиционными параметрами. ExecSQL и RowsAffected.

  • Выполнение запросов возвращающих множество. Метод Open() или свойство Active.

Законченный пример показан на картинке. Для выборки множества, а так же для выпонлнения операций вставки/удаления используется компонент TADOQuery:

Компоненты на форме связаны следующим образом: TADOQuery запрашивает данные у БД, которая указана в TADOConnection и передает их в компонент-посредник TDataSource. TDBGrid умеет отображать данные, которые загружены в TDataSource. Получается следующая схема взаимодействия: ADOConnection->ADOQuery->DataSource (вкладка Data Access)->DBGrid.

Рассмотрим первый вариант использования TADOQuery — выполнение запросов, которые не возвращают результирующее множество:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

// перехватываем все ошибки обращения к БД Firebird/InterBase из Delphi

try

 

  // открываем подключенеи Delphi Firebird

  ADOConnection1.Open();

  ADOConnection1.BeginTrans();

 

  // Позиционные параметры

  with ADOQuery1 do

    begin

        // текст запроса

        with SQL do begin

          Clear;

          Add('DELETE FROM COUNTRY WHERE Country=? and Currency=?');

        end;

 

        with Parameters do begin

             Clear;

             // вариант 1

             AddParameter().Value :='Turkey';

             // вариант 2

             AddParameter();

             Items[1].Value :='Lira';

        end;

 

        // вставка одной записи

        ExecSQL();

        Memo1.Lines.Add ('ExecSQL. Affected Records: ' + IntToStr(ADOQuery1.RowsAffected));

  end;

 

  // Именованные параметры

  with ADOQuery1 do

    begin

        with SQL do begin

          Clear;

          Add('INSERT INTO COUNTRY (country, currency) VALUES (:c1, :c2)');

        end;

 

        // устанавливаем 2 параметра за раз

        Parameters.ParamValues['c1;c2'] := VarArrayOf (['Turkey', 'Lira']);

 

        ExecSQL();

        Memo1.Lines.Add ('ExecSQL. Affected Records: ' + IntToStr(ADOQuery1.RowsAffected));

    end;

 

    ADOConnection1.CommitTrans();

  except on E : Exception do

    // откатываем транзакцию в случае ошибки

    begin

      ADOConnection1.RollbackTrans();

      ShowMessage(E.ClassName+' db error: '+E.Message);

    end;

  end;

 

  // закрываем подключение

  ADOConnection1.Close();

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

1. Одним выражением за раз:

1

ADOQuery1.Parameters.ParamValues['c1;c2'] := VarArrayOf (['Turkey', 'Lira']);

2. И каждый параметр отдельно:

1

2

3

4

5

6

with Parameters do begin

     Clear;

     AddParameter().Value :='Turkey';

     AddParameter();

     Items[1].Value :='Lira';

end;

Для выборки данных через TADOQuery используется SQL-выражение, содержащее команду SELECT, и метод Open():

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

try

 

// открываем подключение Delphi InterBase

ADOConnection1.Open();

ADOConnection1.BeginTrans();

 

  with ADOQuery1 do

   begin

     // текст запроса

     with SQL do begin

        Clear;

        Add('SELECT * FROM EMPLOYEE WHERE EMP_NO > ?');

     end;

 

     with Parameters do begin

        Clear;

        AddParameter().Value :='10';

     end;

 

     // открываем Recordset через метод Open(),

     // вместо этого так же можно установить свойство Active=true

     Open();

   end;

 

ADOConnection1.CommitTrans();

 

except on E : Exception do

 // откат транзакции в случае ошибки

 begin

    ADOConnection1.RollbackTrans();

    ShowMessage(E.ClassName+' db error: '+E.Message);

 end;

 

ADOConnection1.Close();

TADOStoredProc

Компонент TADOStoredProc позволяет выполнять хранимые процедуры InterBase и Firebird. Принцип работы TADOStoredProc такой же как и у TADOQuery:

  • Подключение задается в свойстве Connection или ConnectionString.

  • Метод Open() или свойство Active=true позволяют получить результирующее множество.

  • Метод ExecSQL позволяет выполнить процедуру и вернуть результат в наборе OUT-параметров.

Единственные отличием является свойство ProcedureName в котором определяется имя хранимой процедуры. Свойство SQL в компоненте TADOStoredProc отсутствует

Хранимая процедура может возвращать результат двумя способами:

  • в виде результирующего множества;

  • в виде выходных OUT-параметров;

Для получения результирующего множества используется оператор SELECT:

1

select * from stored_procedure_name(…)

Для выполнения процедуры, которая ничего не возвращает или возвращает OUT-параметры необходимо использовать инструкцию exec:

1

exec procedure stored_procedure_name

Компонент TADOCommand

TADOCommand — команда, которая передается серверу, для того чтобы считать или изменить данные. Компонент фактически объединяет в себе возможности 3-х рассмотренных компонентов: TADOTable, TADOQuery, TADOStoredProc.

Поведение TADOCommand меняется в зависимости от свойства CommandType. Оно может принимать следующие значения:

  • cmdText — текст команды содержит SQL-запрос. Поведение аналогично TADOQuery.

  • cmdStoredProc — в свойстве CommandText задано имя хранимой процедуры. Поведение соответствует компоненту TADOStoredProc.

  • cmdTable и cmdTableDirect — означают, что в тексте указано имя таблицы, которую необходимо загрузить. Для Firebird и InterBase значения cmdTable и cmdTableDirect идентичны. Соответствует TADOTable.

СУБД FireBird является одной из самых популярных в мире бесплатных, кросплатформенных систем управления базами данных с открытым исходным кодом. Она была разработана на основе исходного кода СУБД Interbase и развивается сегодня независимым международным сообществом. По надёжности, производительности и функциональным возможностям эта система мало в чём уступает признанным лидерам своего класса - Oracle и Microsoft SQL Server.

Firebird полностью поддерживает стандартны ANSI в синтаксисе языка SQL и может работать под управлением многих операционных систем - Windows, Linux, MacOS, Solaris и различных Unix-платформах. Среди достоинств этой системы использование очень развитого языка для хранимых процедур и триггеров. Предшественник Firebird, СУБД Interbase использовалась в информационных системах начиная с 1981 года.

Firebird это свободный проект, поддерживаемый многими программистами и специалистами из других областей по всему миру. Его начало было положено 25 июля 2000 года, когда корпорация Inprise Corp (ныне известная как Borland Software Corp) открыла исходные коды своей СУБД Interbase, которая использовалась в различных информационных системах начиная с 1981 года.

Firebird полностью бесплатна, она не требует ни регистрации, ни оплаты за поддержку. Исходный код этой системы открыт и любой желающий может разрабатывать на его базе собственные некоммерческие проекты, при условии соблюдения требований лицензии IDPL, по которой распространяется Firebird.

Firebird (FirebirdSQL) — компактная, кроссплатформенная, свободная система управления базами данных (СУБД), работающая на Linux, Microsoft Windows и разнообразных Unix платформах.

Firebird основан на исходном коде InterBase 6.0 который был выпущен как Open Source компанией Borland в августе 2000 года. История Interbase начинается в 1984 году, таким образом, продукт является наследником более чем 20-летнего опыта работы с реляционными базами данных

В качестве преимуществ Firebird можно отметить многоверсионную архитектуру, обеспечивающую параллельную обработку оперативных и аналитических запросов (это возможно потому, что читающие пользователи не блокируют пишущих), компактность (дистрибутив 5Mb), высокую эффективность и мощную языковую поддержку для хранимых процедур и триггеров.

Firebird используется в различных промышленных системах (складские и хозяйственные, финансовый и государственный сектора) с 2001 г. Это коммерчески независимый проект C и C++ программистов, технических советников и разработчиков мультиплатформенных систем управления базами данных, основанный на исходном коде, выпущенном корпорацией Borland 25 июля 2000 года в виде свободной версии Interbase 6.0.

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

Среди недостатков: отсутствие кэша результатов запросов, полнотекстовых индексов.

Основные характеристики субд Firebird

Соответствие требованиям ACID: Firebird сделан специально, чтобы удовлетворять требованиям “атомарности, целостности, изоляции и надёжности” транзакций (“Atomicity, Consistency, Isolation and Durability”).

Версионная архитектура: Основная особенность Firebird — версионная архитектура, позволяющая серверу обрабатывать различные версии одной и той же записи в любое время таким образом, что каждая транзакция видит свою версию данных, не мешая соседним (“читающие транзакции не блокируют пишущие, а пишущие не блокируют читающих”). Это позволяет использовать одновременно OLTP и OLAP запросы.

Хранимые процедуры: Используя язык PSQL (процедурный SQL) Firebird, возможно создавать сложные хранимые процедуры для обработки данных полностью на стороне сервера. Для генерации отчётов особенно удобны хранимые процедуры с возможностью выборки, возвращающие данные в виде набора записей. Такие процедуры можно использовать в запросах точно так же как и обычные таблицы.

События: Хранимые процедуры и триггеры могут генерировать события, на которые может подписаться клиент. После успешного завершения транзакции (COMMIT) он будет извещён о произошедших событиях и их количестве.

Генераторы: Идея генераторов (последовательностей) делает возможной простую реализацию автоинкрементных полей, и не только их. Генераторы являются 64-битными хранимыми в базе данных счётчиками, работающими независимо от транзакций. Они могут быть использованы для различных целей, таких как генерация первичных ключей, управление длительными запросами в соседних транзакциях, и т. д.

Базы данных только для чтения: позволяют распространять базы данных, к примеру, на CD-ROM. Особенно упрощает распространение данных их использование в комбинации с встраиваемой версией сервера Firebird (Firebird Embedded).

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

Резервное копирование на лету: Для резервного копирования нет надобности останавливать сервер. Процесс резервного копирования сохраняет состояние базы данных на момент своего старта, не мешая при этом работе с базой. Кроме того, существует возможность производить инкрементальное резервное копирование БД.

Триггеры: Для каждой таблицы возможно назначение нескольких триггеров, срабатывающих до или после вставки, обновления или удаления записей. Для триггеров используется язык PSQL, позволяя вносить начальные значения, проверять целостность данных, вызывать исключения, и т. д. В Firebird 1.5 появились “универсальные” триггеры, позволяющие в одном триггере обрабатывать вставки, обновления и удаления записей таблицы.

Внешние функции: библиотеки с UDF (User Defined Function) могут быть написаны на любом языке и легко подключены к серверу в виде DLL/SO, позволяя расширять возможности сервера “изнутри”.

Декларативное описание ссылочной целостности: Обеспечивает непротиворечивость и целостность многоуровневых отношений “master-detail” между таблицами.

Наборы символов: Firebird поддерживает множество международных наборов символов (включая Unicode) с множеством вариантов сортировки.