Firebird/ru

From Free Pascal wiki
Jump to navigationJump to search

English (en) français (fr) русский (ru)

Databases portal

References:

Tutorials/practical articles:

Databases

Advantage - MySQL - MSSQL - Postgres - Interbase - Firebird - Oracle - ODBC - Paradox - SQLite - dBASE - MS Access - Zeos

Это руководство по использованию базы данных 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) и OSX.

В настоящее время сервер портируется на 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, установленных в:

  • каталог проекта и каталог вывода исполняемого файла/каталог приложения (например, lib /что-то еще в каталоге вашего проекта)
  • или каталог в вашем PATH (не в системном каталоге)
  • Если вы хотите использовать системный каталог, пожалуйста, используйте официальный установщик и поставьте галочку «скопировать fbclient в системный каталог»

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

Unix/Linux/OSX

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

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

  • использовать компонент TSQLDBLibraryLoader из sqldblib (FPC 2.7.1). Работает для всех компонентов коннектора SQLDB.
  • вызвать функцию
    function InitialiseIBase60(Const LibraryName : AnsiString) : integer;
    
    с правильным именем библиотеки (для этого может потребоваться использовать модуль ibase60dyn).

Connection examples

Example for client/server:

Hostname: 192.168.1.1
* The database is on the server with IP address 192.168.1.1. 
DatabaseName: /interdata/example.fdb  
* The name of the database file is "example.fdb" in the /interdata directory of the server (the machine with IP address 192.168.1.1).
Username: SYSDBA
Password: masterkey

Another example for client/server:

Hostname: dbhost
* The database is on the server with the host name dbhost
DatabaseName: F:\Program Files\firebird\examples\employee.fdb  
* The name of the database file is "employee.fdb" in the Program Files\firebird\examples directory on the F: drive of dbhost.
Username: SYSDBA
Password: masterkey

An embedded example:

Hostname: <empty string>
* Leaving the hostname empty selects embedded use.
DatabaseName: test.fdb
* The database file is "test.fdb" in the directory where the application runs (make sure fbembed.dll is in the application executable directory)
Username: SYSDBA
* On embedded, you do have to specify a username...
Password: <empty string>
* ... but it doesn't matter what password you give.

Troubleshooting client/server access issues

Make sure you started the Interbase/Firebird server on the server IP/hostname you specified. You can test connectivity by telnetting to the machine. Firebird usually listens on port 3050:

telnet 192.168.1.1 3050

You should see something, maybe just a blank screen, but you can type something. This means you can send data to the Firebird database.

For further information, please see the Firebird documentation.

Monitoring Events

FPC/Lazarus comes with a component to monitor events coming from Firebird databases; see TFBEventMonitor.

Creating objects programmatically

While you can use tools such as Flamerobin to create tables etc, you can also create these programmatically/dynamically, which could be handy when you want your programs to update existing database schemas to a new schema.

You can use e.g. TSQLQuery.ExecSQL to perform this task:

Query.ExecSQL('CREATE TABLE TEST(ID INTEGER NOT NULL, TESTNAME VARCHAR(800))');
// You need to commit the transaction after DDL before any DML - SELECT, INSERT etc statements.
// Otherwise the SQL won't see the created objects

To do this, use the TSQLScript object - see TSQLScript.

Database Administration

FPC/Lazarus has a component for database adminstration; see TFBAdmin

Common problems and solutions

Sometimes using Firebird in Lazarus seems to be tricky. Please find solutions below.

Attempted update of read-only column / COMPUTED BY fields

If you have COMPUTED BY fields (server-side calculated fields) in your Firebird table, SQLDB will not pick up that these are read only fields (for performance reasons).

In this case, auto-generated INSERTSQL,UPDATESQL statements can lead to error messages like "attempted update of read-only column". The solution is to manually specify that the field in question may not be updated after setting the TSQLQuery's SQL property, something like:

// Disable updating this field or searching for changed values as user cannot change it
sqlquery1.fieldbyname('full_name').ProviderFlags:=[];

Bigint: lost precision

If you use the bigint datatype (64 bit signed integer) in Firebird, please use .AsLargeInt instead of .AsInteger for parameters:

// Assuming ID is bigint here
sqlquery1.sql.text := 'insert into ADDRESS (ID) values (:ID)';
// Use this:
sqlquery1.params.parambyname('ID').aslargeint := <some qword or 64 bit integer variable>;
// Do not use this:
//sqlquery1.params.parambyname('ID').asinteger := <some qword or 64 bit integer variable>;
...

... otherwise you might get errors like duplicate PK (primary key) - if using the bigint as a primary key.

Boolean data types

Firebird versions below 3.0 do not support boolean data types.

At least on FPC trunk (2.7.1) this datatype can be emulated:

Use a DOMAIN that uses a SMALLINT type (other integer types may work as well - please test and adjust text):

CREATE DOMAIN "BOOLEAN"
 AS SMALLINT
 CHECK (VALUE IS NULL OR VALUE IN (-1,0,1))
 /* -1 used for compatibility with FPC SQLDB; 1 is used by many other data access layers */
;


Let your field/column use this domain type e.g.

CREATE TABLE MYTABLE
(
...
  MYBOOLEANCOLUMN "BOOLEAN",
);
  • Now you can use .AsBoolean for assigning field values etc

To do: verify this works with Lazarus grids etc as well.

INSERT INTO...RETURNING problems/Cursor is not open =

If you try to select SQL (e.g. Query.Open) with SQL like this:

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

and get something like this error:

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

while running FPC 2.6.0 (which is supplied with Lazarus 1.0) or lower, then you probably ran into an FPC SQLDB parser bug.

SQLDB thinks the statement you're running is a normal INSERT statement, which doesn't return data. Obviously, it should return data. Newer FPC code has fixes for this.

If you're using generators/sequences for your primary keys (like many do), a workaround is to first get the next sequence number:

SELECT NEXT VALUE FOR GEN_PEOPLEID FROM RDB$DATABASE /* If your generator name is GEN_PEOPLEID */

then use that to do a regular INSERT. see FAQ entry

Locate does not seem to work

Source: Issue ##21988

When running locate on UTF8 (or presumably other multibyte character sets) CHAR fields, locate may not find your record.

The problem is related mostly to UTF8 charset used and how Firebird reports column length. In case of UTF8 Firebird reports the maximum column length (in bytes) as 4*"character length". So if you have a column defined as char(8), Firebird reports 4*8=32.

Values are right-padded to this length 32. When locating say '57200001' there is no match because the field actually stores '57200001 ........................' (with trailing spaces represented by dots here).

Workaround: rewrite your select query:

SELECT substring(THEFIELD from 1 for 8) AS THEFIELD ...
or
SELECT cast(THEFIELD as varchar(8)) as THEFIELD ...

or use VARCHAR fields.

Note: this problem may occur for other databases as well depending on their reporting of field length.

Advanced transactions

Sources for this information/further reading:

Transaction isolation levels

If you want to, you can change the transaction isolation levels by adding a line in the transaction's Parameters property:

  • isc_tpb_read_committed: you see all changes committed by other transactions
  • isc_tpb_concurrency: also called Snapshot: you see database as it was when the transaction started. Has more overhead than isc_tpb_read_committed. Better than ANSI Serializable because it has no phantom reads.
  • isc_tpb_consistency: also called Table Stability: stable, serializable view of data, but locks tables. Unlikely you will need this

Example:

SQLTransaction1.Params.text:='isc_tpb_read_committed';

You can also add additional parameters that have an effect on the transaction (taken from the ibconnection.pp source file and [1]):

Access mode

This allow reads only or read/write

  • isc_tpb_read: read permission
  • isc_tpb_write: read+write permission

Lock resolution

  • isc_tpb_nowait: if another transaction is editing the record then don't wait
  • isc_tpb_wait: if another transaction is editing the record then wait for it to finish. Can mitigate "live locks" in heavy contention ([2]). See below for timeout value.

Table reservation

Deals with locking entire tables.

  • isc_tpb_shared: first specify this, then either lock_read or lock_write for one or more tables. Shared read or write mode for tables.
  • isc_tpb_protected: first specify this, then either lock_read or lock_write for one or more tables. Lock on tables; can allow deadlock-free operation at the cost of delayed transactions
  • isc_tpb_lock_read: Set a read lock. Specify which table to lock, e.g. isc_tpb_lock_read=CUSTOMERS
  • isc_tpb_lock_write: Set a read/write lock. Specify which table to lock, e.g. isc_tpb_lock_read=CUSTOMERS

Combinations:

  • Shared, lock_write: write transactions with concurrency or read committed isolation

can update the table. All transactions can read the table

  • Shared, lock_read: any transaction can read or update
  • Protected, lock_write: Other transactions cannot update the table. Only concurrency and

read committed transactions can read the table

  • Protected, lock_read: Other transactions cannot update the table. Any transaction can

read the table

Record versions

This setting is apparently only relevant for isc_tpb_read_committed isolation mode for records being modified by other transactions:

  • isc_tpb_no_rec_version: only newest record version is read. Can be useful for batch/bulk insert operations together with isc_tpb_read_committed)
  • isc_tpb_rec_version: the latest committed version is read, even when the other transaction has other uncommitted changes note: verify this. More overhead than isc_tpb_no_rec_version

Various options

For completeness, some more options appearing in the Firebird/Interbase FPC code. You will likely only ever use isc_tpb_no_auto_undo to speed up batch inserts/edits.

  • isc_tpb_exclusive (apparently translates to protected in Firebird, see [3])
  • isc_tpb_verb_time (Related to deferred constraints, which could execute at verb time or commit time. Firebird: not implemented, always use verb time)
  • isc_tpb_commit_time (Related to deferred constraints, which could execute at verb time or commit time. Firebird: not implemented, always use verb time)
  • isc_tpb_ignore_limbo (ignores the records created by transactions in limbo. Limbo transactions are failing two-phase commits in multi-database transactions. Unlikely that you will need this feature)
  • isc_tpb_autocommit (autocommit this transaction: every statement is a separate transaction. Probably specifically for JayBird JDBC driver.)
  • isc_tpb_restart_requests (apparently looks for requests in the connection which had been active in another transaction, unwinds them, and restarts them under the new transaction.)
  • isc_tpb_no_auto_undo (disable transaction-level undo log, handy for getting max throughput when performing a batch update. Has no effect when only reading data.)
  • isc_tpb_lock_timeout (specify number of seconds to wait for lock release, if you use isc_tpb_wait. If this value is reached without lock release, an error is reported.)

Firebird and ISO transactions

Firebird transaction do not map 1 to 1 to ISO/ANSI transaction levels. An approximation is:

  • ISO Read Committed=READ COMMITTED+RECORD_VERSION
  • ISO Read Committed=READ COMMITTED+NO RECORD_VERSION
  • ISO Repeatable Read=SNAPSHOT (also known as CONCURRENCY)
  • ISO Serializable=SNAPSHOT TABLE STABILITY (also known as CONSISTENCY)

Common combinations

Default is (probably, will have to check) read committed.

Batch/bulk insert

isc_tpb_read_committed and isc_tpb_no_rec_version could be a good combination: it allows other transactions to function while the batch is going on.

Read only transaction

If you want to only have read access to the database, you can do so by setting these transaction parameters:

  • isc_tpb_read
  • isc_tpb_read_committed
  • isc_tpb_rec_version
  • nowait

This combination will not block garbage collection, which is a good thing. Source: [4]

Note: the Firebird FAQ indicates you will need write access to the database file even if you only read from it, unless you set the database read-only flag (e.g. using gfix).

Links and more information

The list below shows links to more information on Firebird and related tools.

Lazarus Firebird samples

Tools

  • FlameRobin Flamerobin site Open source GUI tool to manage Firebird, available for Linux, Windows and Mac OSX. Highly recommended.
  • Turbobird Turbobird site Open source GUI tool to manage Firebird. Written with Lazarus using TIBConnection
  • ibconsole : Tool to manage Firebird an Interbase Databases with a GUI, available for Windows and Linux
  • Lazarus Data Desktop - included in the Lazarus repository (found in the 'tools/lazdatadesktop/' directory)
  • LazSQLX Multi-database open source database management tool. Written with Lazarus using both SQLDB and Zeos components. Includes support for Firebird.
  • tiSQLEditor - included in the "Support Apps" directory of the tiOPF repository. It is a tool used to write SQL with some code completion support, can run scripts, execute upgrade scripts for applications from one build to a later build, has various handy copy and paste functions for Object Pascal applications, has many features that are useful to tiOPF (creates Object Pascal code templates from query results, for tiOPF's visitor classes), export query results to CSV etc.

Firebird

  • The Firebird RDBMS Firebird site. This site also contains a lot of documentation on Firebird.
  • Firebird FAQ [6]. Handy site that shows e.g. differences with other RDBMS.
  • New site that shows how to use the latest tools and LibreOffice, FPC to be added soon Firebird