Sign in Join
Wiki copytemporary

Firebird/ru

English · Français · Русский · 日本語

Это руководство по использованию базы данных Firebird в Lazarus/FPC, с использованием Firebird с SQLDB (встроенная библиотека базы данных FPC/Lazarus). Другие методы доступа описаны в разделе Другие библиотеки Firebird.

Обзор

Firebird - это бесплатный сервер баз данных с открытым исходным кодом, который использовался и разрабатывался десятилетиями (он разрабатывался на основе базы данных Interbase 6, исходные коды которой были открыты компанией Borland). Он включает в себя расширенную поддержку операторов SQL (например, INSERT...RETURNING), хранимых процедур, триггеров и т.д. Вы можете написать скомпилированные библиотеки UDF (библиотеки пользовательских функций) для сервера в FreePascal, если вы хотите расширить и без того обширный список функций Firebird.

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

Firebird предлагает как встроенную (основанную на файлах), так и клиент-серверную базу данных - которую можно использовать без необходимости изменять одну строку кода в FPC/Lazarus. При использовании в качестве встроенной базы данных она предлагает более богатую поддержку SQL, чем SQLite, а также плавную миграцию в базу данных клиент-сервер, хотя SQLite сама по себе является вполне встроенной базой данных.

Последняя стабильная версия, Firebird 2.5 (прим.перев.: на момент перевода статьи - это версия Firebird 3.0.4), работает в Windows (32- и 64-разрядная версия), различных версиях Linux (32- и 64-разрядная версия), Solaris (Sparc и Intel), HP-UX (PA-Risc) и macOS.

В настоящее время сервер портируется на Android; он пока недоступен в Windows CE/Windows Mobile.

Поддержка Firebird в SQLDB компилятора довольно хорошая, сравнимая с уровнем поддержки PostgreSQL.

Документация

Официальная документация включена в FPC 2.6.2+: Документация SQLDB для IBConnection

Установка режимов клиент/сервер и встроенного режима сервера

Firebird может работать в режиме клиент/сервер и в режиме встроенного сервера.

Client/Server означает, что у вас где-то есть физический сервер Firebird: либо на локальной машине, либо на другой машине, доступной по вашей сети. Соединения с сервером проходят через TCP/IP; при указании соединения имя хоста содержит имя или IP-адрес. Серверу Firebird для "общения" с вашими компонентами доступа необходима fbclient.dll/fbclient.so.nnn (вместе с его файлами поддержки).

Embedded Firebird означает, что ваше приложение для доступа к базе данных Firebird на локальной машине загружает единственную библиотеку, которая является и сервером, и клиентской библиотекой Firebird "в одном флаконе". При указании строки соединения имя хоста всегда пусто (не указывается). Серверу Firebird для "общения" с вашими компонентами доступа необходима fbembed.dll/fbembed.so (вместе с его файлами поддержки). См. вики-страницу на Firebird embedded для более подробной информации.

Обратите внимание, что fbembed.dll может использоваться как для клиент-серверного, так и для встроенного использования, поэтому установка только этой dll может быть разумной задачей.


Прим.перев.: необходимо уточнить, что выше описанное справедливо для версий FB 1.5, FB 2.0, FB 2.1 и FB 2.5. Начиная с версии FB 3.0, режим используемого сервера зависит от строки подключения, а клиентская библиотека на все случаи жизни одна - все та же fbclient.dll/libfbclient.so.3.0.n (где n - номер билда версии FB).


Windows

Win64: пожалуйста, см. предупреждение здесь о нежелательном использовании некоторых версий FPC/Lazarus Win64.

Для Windows: (это относится ко всем драйверам базы данных SQLDB) необходимо иметь fbclient.dll (или fbembed.dll' ) и его поддержку dll, установленных в:

Как и для всех библиотек DLL (базы данных), разрядность библиотеки DLL должна соответствовать вашему приложению: используйте 32-разрядную библиотеку для 32-разрядной скомпилированной программы и 64-разрядную библиотеку для 64-разрядной программы.

Unix/Linux/macOS

В Linux/macOS/FreeBSD должна быть установлена ​​клиентская библиотека Firebird (например, вашим менеджером пакетов; установите обычный пакет и пакет -dev), или они должны быть прописаны в путях поиска библиотеки.

FPC ищет наиболее распространенные имена библиотек (например, libfbclient.so.2.5, libgds.so и libfbembed.so.2.5; пожалуйста, проверьте ibase60.inc, если ваша версия отличается). При желании можно указать имя библиотеки. Есть 2 способа сделать это:

Примеры подключения

1. Пример для client/server:

Hostname: 192.168.1.1
* База данных находится на сервере с IP-адресом 192.168.1.1.
DatabaseName: /interdata/example.fdb  
* Имя файла базы данных - "example.fdb" в каталоге /interdata сервера (машина с IP-адресом 192.168.1.1).
Username: SYSDBA
Password: masterkey

2. Другой пример client/server:

Hostname: dbhost
* База данных находится на сервере с именем хоста dbhost
DatabaseName: F:\Program Files\firebird\examples\employee.fdb  
* Имя файла базы данных - "employee.fdb" в каталоге Program Files\firebird\examples на диске F: dbhost.
Username: SYSDBA
Password: masterkey

3. Пример для embedded-режима:

Hostname: <пустая строка>
* Оставляя имя хоста пустым, выбирается embedded-режим.
DatabaseName: test.fdb
* Файл базы данных "test.fdb" находится в каталоге запускаемого приложения (убедитесь, что fbembed.dll находится в каталоге исполняемого файла приложения)
Username: SYSDBA
* Для встроенного сервера вы должны указать имя пользователя ...
Password: <пустая строка> (прим.перев.: вообще-то, это может быть любая строка, в т.ч. и пустая)
* ... но не важно, какой пароль вы укажете.


Прим.перев.: выше приведенные примеры подразумевают, что используется порт по умолчанию 3050. Если номер порта отличается от стандартного (например, пусть будет 3051), то для каждого из выше приведенных примеров строка подключения (например, к утилите isql) соответственно будет выглядеть следующим образом:

bash
SQL>connect '192.168.1.1/3051:/interdata/example.fdb' -user 'SYSDBA' -password 'masterkey';
bash
SQL>connect 'dbhost/3051:F:\Program Files\firebird\examples\employee.fdb' -user 'SYSDBA' -password 'masterkey';
bash
SQL>connect 'test.fdb' -user 'SYSDBA' -password '';

Начиная с версии FB 3 появилась возможность указывать другие протоколы коннекта:

Тогда строка подключения (например, к утилите isql) для выше указанных примеров соответственно будет выглядеть так:

bash
SQL>connect 'inet://192.168.1.1:3051:/interdata/example.fdb' -user 'SYSDBA' -password 'masterkey';
bash
SQL>connect 'inet://dbhost:3051:F:\Program Files\firebird\examples\employee.fdb' -user 'SYSDBA' -password 'masterkey';
bash
SQL>connect 'inet://test.fdb' -user 'SYSDBA' -password '';

INET-протокол поддерживает URL-стиль (для адресов IPv4 и IPv6) строки подключения вы виде шаблона [<protocol>://[<host>[:<port>]]]/<database file path or alias>. Тогда в строке подключения часть строки заменяется с inet:// на inet4:// или inet6:// соответственно. Например:

bash
SQL>connect 'inet6://192.168.1.1:3051:/interdata/example.fdb' -user 'SYSDBA' -password 'masterkey';

Note: по умолчанию Firebird прослушивает нулевой адрес IPv6 (: :) и принимает все входящие соединения, будь то IPv4 или IPv6. Если эти адреса имеют ненулевое значение, то в строке подключения они обрамляются квадратными скобками, чтобы устранить двусмысленность при использовании двоеточия в качестве разделителя

.

Например, если IPv6 = 2014:1234::5, то строка подключения примет вид:

bash
SQL>connect '[2014:1234::5]://192.168.1.1:3051:/interdata/example.fdb' -user 'SYSDBA' -password 'masterkey';

и далее по аналогии...

Последние два протокола имеют строку подключения, аналогичную INET, только вместо inet:// подставляются wnet:// или xnet:// соответственно.

Более подробную информацию по нововведениям FB 3, в том числе и по протоколам коннекта можно посмотреть здесь.


Устранение проблем с доступом client/server

Убедитесь, что вы запустили сервер Interbase/Firebird на указанном вами IP-адресе/имени хоста сервера. Вы можете проверить подключение, подключившись к компьютеру через telnet. Firebird обычно слушает порт 3050:

bash
telnet 192.168.1.1 3050

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

Для получения дополнительной информации см. документацию Firebird.

Мониторинг событий

FPC/Lazarus поставляется с компонентом для мониторинга событий, поступающих из баз данных Firebird; см. TFBEventMonitor.

Программное создание объектов

Хотя для создания таблиц и т.д. можно использовать такие инструменты, как Flamerobin (прим.перев.: для windows, особенно русскоязычной, предпочтительнее использовать IBExpert), вы также можете создавать объекты БД программно/динамически, что может быть удобно, если вы хотите, чтобы ваши программы обновляли существующие схемы базы данных до новой схемы.

Вы можете использовать, например, TSQLQuery.ExecSQL для выполнения этой задачи:

pascal
Query.ExecSQL('CREATE TABLE TEST(ID INTEGER NOT NULL, TESTNAME VARCHAR(800))');
// Вам необходимо закомиттить транзакцию после DDL перед любыми инструкциями DML - SELECT, INSERT и т. Д.
//В противном случае SQL не увидит созданные объекты

Используйте для этих целей объект TSQLScript - см. TSQLScript.

Администрирование базы данных

У FPC/Lazarus есть компонент для администрирования базы данных; см. TFBAdmin

Общие проблемы и решения

Иногда использование Firebird в Lazarus кажется сложным. Пожалуйста, поищите решения ниже по тексту.

Попытка обновления доступного только для чтения столбца / полей COMPUTED BY

Если в вашей таблице Firebird есть поля COMPUTED BY (вычисляемые поля на стороне сервера), SQLDB не будет брать в расчет, что это поля только для чтения (из соображений производительности).

В этом случае автоматически сгенерированные операторы INSERTSQL, UPDATESQL могут привести к сообщениям об ошибках, таких как "attempted update of read-only column" (попытка обновления столбца только для чтения).Решение состоит в том, чтобы вручную указать, что данное поле не может быть обновлено после установки свойства SQL в TSQLQuery, что-то вроде:

pascal
// Отключаем обновление этого поля или поиск измененных значений, поскольку пользователь не может изменить его
sqlquery1.fieldbyname('full_name').ProviderFlags:=[];

Bigint: потеря точности

Если вы используете тип данных bigint (64-битное целое число со знаком) в Firebird, пожалуйста, используйте .AsLargeInt вместо .AsInteger для параметров:

pascal
// Предполагая, что идентификатор здесь bigint
sqlquery1.sql.text := 'insert into ADDRESS (ID) values (:ID)';
// делаем так:
sqlquery1.params.parambyname('ID').aslargeint := <?????????? qword- ?????? 64-bit integer-????????????????????>;
// Не делайте так:
//sqlquery1.params.parambyname('ID').asinteger := <любая qword- или 64-bit integer-переменная>;
...

... в противном случае вы можете получить такие ошибки, как дубликат PK (первичного ключа) - при использовании bigint в качестве первичного ключа.

Логические типы данных

Версии Firebird ниже 3.0 не поддерживают логические типы данных.

По крайней мере, в транке FPC (2.7.1) этот тип данных можно эмулировать:

Используйте домен, который использует тип SMALLINT (другие целочисленные типы также могут работать - пожалуйста, протестируйте и настройте текст):

sql
CREATE DOMAIN "BOOLEAN"
 AS SMALLINT
 CHECK (VALUE IS NULL OR VALUE IN (-1,0,1))
 /* -1 используется для совместимости с SQLDB FPC; 1 используется многими другими слоями доступа к данным */
;

Позвольте вашему полю/столбцу использовать этот тип домена, например

sql
CREATE TABLE MYTABLE
(
...
  MYBOOLEANCOLUMN "BOOLEAN",
);

To do: убедитесь, что это работает с гридами Lazarus и т. д..

Проблемы INSERT INTO...RETURNING/Не открытый курсор

Если вы попытаетесь сделать выборку SQL (например, Query.Open) в следущем SQL-запросе:

sql
INSERT INTO PEOPLE (NICKNAME) VALUES ('Superman') RETURNING ID

и получаете что-то вроде этой ошибки:

dos
Database error:  : Fetch :
 -Dynamic SQL Error
 -SQL error code = -504
 -Invalid cursor reference
 -Cursor is not open(error code: 335544569)

во время работы FPC 2.6.0 (которая поставляется с Lazarus 1.0) или ниже, вы, вероятно, столкнулись с ошибкой синтаксического парсера FPC SQLDB.

SQLDB считает, что выполняемый вами оператор является обычным оператором INSERT, который не возвращает данные. Очевидно, он должен возвращать данные. В более новом FPC для этого кода уже внесены исправления.

Если вы используете генераторы/последовательности для своих первичных ключей (как это делают многие), в качестве обходного пути вы должны сначала получить следующий порядковый номер:

sql
SELECT NEXT VALUE FOR GEN_PEOPLEID FROM RDB$DATABASE /* Если имя вашего генератора GEN_PEOPLEID */

затем используйте это, чтобы сделать обычный INSERT. см. FAQ entry


Прим.перев.: вообще-то, мягко говоря, немного странный совет. Гораздо проще и безопаснее создать в БД триггер BeforeInsert примерно следующего содержания:

sql
/* Trigger: TBL_PEOPLE_BI */
CREATE OR ALTER TRIGGER TBL_PEOPLE_BI FOR TBL_PEOPLE
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
  /* генерируем новое значение поля, если вставляемое является NULL-значением */
  IF (NEW.ID IS NULL) THEN 
    NEW.ID = GEN_ID(GEN_PEOPLEID,1);
END
^

чтобы переложить заботу о генерации PK на плечи сервера, передавая с клиента NULL-значение генератора (или не передавая его вообще, что будет восприниматься сервером, как NULL).


Locate, кажется, не работает

Источник: Issue ##21988

При запуске locate в CHAR-полях с UTF8 (или, возможно, других многобайтовых символов), locate может не найти вашу запись.

Проблема в основном связана с используемой кодировкой UTF8 и тем, как Firebird сообщает о длине столбца. В случае UTF8 Firebird сообщает о максимальной длине столбца (в байтах) как 4 * «размер символа». Поэтому, если у вас есть столбец, определенный как char(8), Firebird сообщает 4*8=32.

Значения "добиваются" пробелами справа до этой длины 32. При поиске, скажем, «57200001», совпадений нет, потому что в поле фактически хранится «57200001 ........................» (с конечными пробелами, представленными здесь точками ).

Обходной путь: перепишите ваш select-запрос:

sql
SELECT substring(THEFIELD from 1 for 8) AS THEFIELD ...

или

sql
SELECT cast(THEFIELD as varchar(8)) as THEFIELD ...

или используйте VARCHAR-тип полей.

Note: эта проблема может возникать и для других баз данных, в зависимости от их возвращаемой длины.

Подробнее о транзакциях

Источники для этой информации / дальнейшего чтения:

Уровни изоляции транзакций

Если вы хотите, вы можете изменить уровни изоляции транзакции, добавив строку в свойстве Parameters транзакции:

Пример:

pascal
SQLTransaction1.Params.text:='isc_tpb_read_committed';

Вы также можете добавить дополнительные параметры, которые влияют на транзакцию (взятые из исходного файла ibconnection.pp и 1):

Режим доступа

Этот параметр позволяет или только чтение, или чтение/запись

Обработка конфликтов блокировки

Резервирование таблиц

Соглашение по блокировкам таблиц в целом.

Комбинации:

Версионность записей

Этот параметр, по-видимому, относится только к режиму изоляции isc_tpb_read_committed для записей, изменяемых другими транзакциями:

Различные варианты

Для полноты, в коде Firebird/Interbase FPC появилось еще несколько опций. Скорее всего, вы будете использовать isc_tpb_no_auto_undo только для ускорения вставки/редактирования пакетов.

Firebird и транзакции по стандарту ANSI/ISO SQL

Транзакции Firebird не соответствуют 1 в 1 уровню транзакции стандарта ISO/ANSI. Приблизительно так:

Общие комбинации

По умолчанию (возможно, придется проверить) read committed.

Пакетная/массовая вставка

isc_tpb_read_committed и isc_tpb_no_rec_version могут быть хорошей комбинацией: она позволяет другим транзакциям функционировать во время выполнения пакетной вставки.

Транзакции только для чтения

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

Эта комбинация не будет блокировать сборку мусора, что само по себе хорошо. Источник: 4

Note: Firebird FAQ указывает, что вам понадобится доступ с правом записи в файл базы данных, даже если вы только читаете из него, если вы не установите флаг базы данных read-only [только для чтения] (например, с помощью утилиты gfix).

Ссылки и дополнительная информация

В списке ниже приведены ссылки на дополнительную информацию о Firebird и связанных с ней инструментах.

Примеры Lazarus Firebird

Инструменты администрирования

Firebird


From the Free Pascal wiki, page "Firebird/ru", as it stood on 2020-02-16 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's Licensing page. If you have concerns about this material, message the admin.

Revision 2, last changed by WikiArchive .

Talk about this page

Nobody has opened a bench for this page yet. Sign in to open one.