Sign in Join
Wiki copytemporary

Firebird: what changed

Revision 2 to 3. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11This is a guide about using **Firebird** database in Lazarus/FPC, using Firebird with SQLDB (the FPC/Lazarus built-in database library). Other access methods are described in [[Other Firebird libraries]].
22
33## Overview
44
55Firebird is an open source, free database server that has been in use and developed for decades (it developed out of the Interbase 6 database that was open sourced by Borland). It includes rich support for SQL statements (e.g. INSERT...RETURNING), stored procedures, triggers, etc. You can write compiled UDFs (User-Defined Functions) libraries for the server in FreePascal if you want to extend the already extensive function list of Firebird.
66
77The database requires very little manual DBA work once it is set up, making it ideal for small business use or embedded use. It can grow to terabyte scale given proper tuning, although PostgreSQL may be a better choice for such large environments.
88
99Firebird offers both embedded (file-based) and client-server database - usable without having to change a single line of code in FPC/Lazarus. If used as an embedded database, it offers a richer SQL support than [[SQLite]] as well as seamless migration to a client-server database, although SQLite is a quite capable embedded database itself.
1010
1111The latest stable version, Firebird 2.5, runs on Windows (32- and 64-bit), various Linux versions (32- and 64-bit), Solaris (Sparc and Intel), HP-UX (PA-Risc) and OSX.
1212
1313It is being ported to Android at the moment; it is not available on Windows CE/Windows Mobile.
1414
1515Support for Firebird in FPC's SQLDB is quite good, comparable to the level of [[postgres|PostgreSQL]] support.
1616
1717## Documentation
1818
1919Official documentation is included in FPC 2.6.2+: [SQLDB documentation for IBConnection](http://www.freepascal.org/docs-html/fcl/ibconnection/index.html)
2020
2121## Client/server and embedded installation
2222
2323Firebird can run in client/server and embedded mode.
2424
2525*Client/Server* means that you have a physical Firebird server somewhere: either on your local machine or another machine reachable over your network. Connections to the server go through TCP/IP; when specifying the connection, the hostname contains a name or IP address. The Firebird DLL you need for this is *fbclient.dll* (*along with its support files*).
2626
2727*Embedded Firebird* means that your application loads the Firebird DLLs to access a Firebird database on the local machine. When specifying the connection, the hostname is always empty. The Firebird DLL you need for this is *fbembed.dll* (*along with its support files*). See [[Firebird embedded|the wiki page on Firebird embedded]] for more details.
2828
2929Note that *fbembed.dll* can be used both for client/server and embedded use, so installing only this dll may be a smart thing to do.
3030
3131### Windows
3232
3333Win64: please see warning [[Windows Programming Tips|here]] on not using certain FPC/Lazarus Win64 versions.
3434
3535On Windows: (this applies to all SQLDB database drivers) you must have **fbclient.dll** (or **fbembed.dll**) and its support dlls installed in:
3636
3737- the project directory **and** the executable output directory/the application directory (e.g. lib/something under your project directory)
3838- or a directory in your PATH (not your system directory)
3939- If you want to use the system directory, please use the official installer and tick "copy fbclient to system directory"
4040
4141As with all (database) DLLs, the bitness of the DLL must match your application: use a 32 bit library for a 32 bit compiled program and a 64 bit library for a 64 bit program.
4242
4343### Unix/Linux/macOS
4444
4545On FreeBSD/Linux/macOS, the Firebird client library should be installed (e.g. by your package manager; install the regular package and the -dev package), or they should be placed in the library search path.
4646
4747FPC searches for the most common library names (e.g. libfbclient.so.2.5, libgds.so, and libfbembed.so.2.5; please check ibase60.inc if your version is different). If you want to, you can explicitly specify the library name. There are 2 ways for this:
4848
4949- use the [[TSQLDBLibraryLoader]] component from sqldblib (FPC 2.7.1). Works for all SQLDB connector components.
5050- call
5151 ``` pascal
5252 function InitialiseIBase60(Const LibraryName : AnsiString) : integer;
5353 ```
5454
5555 with the correct library name (you may need to use unit ibase60dyn for this).
5656
5757## Connection examples
5858
5959Example for client/server:
6060
61-`Hostname: 192.168.1.1`\
62-`* The database is on the server with IP address 192.168.1.1. `\
63-`DatabaseName: /interdata/example.fdb  `\
64-`* 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).`\
65-`Username: SYSDBA`\
66-`Password: masterkey`
61+```text
62+Hostname: 192.168.1.1
63+* The database is on the server with IP address 192.168.1.1.
64+DatabaseName: /interdata/example.fdb
65+* 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).
66+Username: SYSDBA
67+Password: masterkey
68+```
6769
6870Another example for client/server:
6971
70-`Hostname: dbhost`\
71-`* The database is on the server with the host name dbhost`\
72-`DatabaseName: F:\Program Files\firebird\examples\employee.fdb  `\
73-`* The name of the database file is "employee.fdb" in the Program Files\firebird\examples directory on the F: drive of dbhost.`\
74-`Username: SYSDBA`\
75-`Password: masterkey`
72+``` pascal
73+Hostname: dbhost
74+* The database is on the server with the host name dbhost
75+DatabaseName: F:\Program Files\firebird\examples\employee.fdb
76+* The name of the database file is "employee.fdb" in the Program Files\firebird\examples directory on the F: drive of dbhost.
77+Username: SYSDBA
78+Password: masterkey
79+```
7680
7781An embedded example:
7882
79-`Hostname: <empty string>`\
80-`* Leaving the hostname empty selects embedded use.`\
81-`DatabaseName: test.fdb`\
82-`* The database file is "test.fdb" in the directory where the application runs (make sure fbembed.dll is in the application executable directory)`\
83-`Username: SYSDBA`\
84-`* On embedded, you do have to specify a username...`\
85-`Password: <empty string>`\
86-`* ... but it doesn't matter what password you give.`
83+```text
84+Hostname: <empty string>
85+* Leaving the hostname empty selects embedded use.
86+DatabaseName: test.fdb
87+* The database file is "test.fdb" in the directory where the application runs (make sure fbembed.dll is in the application executable directory)
88+Username: SYSDBA
89+* On embedded, you do have to specify a username...
90+Password: <empty string>
91+* ... but it doesn't matter what password you give.
92+```
8793
8894## Troubleshooting client/server access issues
8995
9096Make 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:
9197
9298``` bash
9399telnet 192.168.1.1 3050
94100```
95101
96102You should see something, maybe just a blank screen, but you can type something. This means you can send data to the Firebird database.
97103
98104For further information, please see the Firebird documentation.
99105
100106## Monitoring Events
101107
102108FPC/Lazarus comes with a component to monitor events coming from Firebird databases; see [[TFBEventMonitor]].
103109
104110## Creating objects programmatically
105111
106112While 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.
107113
108114You can use e.g. TSQLQuery.ExecSQL to perform this task:
109115
110116``` pascal
111117Query.ExecSQL('CREATE TABLE TEST(ID INTEGER NOT NULL, TESTNAME VARCHAR(800))');
112118// You need to commit the transaction after DDL before any DML - SELECT, INSERT etc statements.
113119// Otherwise the SQL won't see the created objects
114120```
115121
116122To do this, use the TSQLScript object - see [[TSQLScript]].
117123
118124## Database Administration
119125
120126FPC/Lazarus has a component for database adminstration; see [[TFBAdmin]]
121127
122128## Common problems and solutions
123129
124130Sometimes using Firebird in Lazarus seems to be tricky. Please find solutions below.
125131
126132### Attempted update of read-only column / COMPUTED BY fields
127133
128134If 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).
129135
130136In 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:
131137
132138``` pascal
133139// Disable updating this field or searching for changed values as user cannot change it
134140sqlquery1.fieldbyname('full_name').ProviderFlags:=[];
135141```
136142
137143### Bigint: lost precision
138144
139145If you use the bigint datatype (64 bit signed integer) in Firebird, please use .AsLargeInt instead of .AsInteger for parameters:
140146
141147``` pascal
142148// Assuming ID is bigint here
143149sqlquery1.sql.text := 'insert into ADDRESS (ID) values (:ID)';
144150// Use this:
145151sqlquery1.params.parambyname('ID').aslargeint := <some qword or 64 bit integer variable>;
146152// Do not use this:
147153//sqlquery1.params.parambyname('ID').asinteger := <some qword or 64 bit integer variable>;
148154...
149155```
150156
151157... otherwise you might get errors like duplicate PK (primary key) - if using the bigint as a primary key.
152158
153159### Boolean data types
154160
155161Firebird versions below 3.0 do not support boolean data types.
156162
157163At least on FPC trunk (2.7.1) this datatype can be emulated:
158164
159165Use a DOMAIN that uses a SMALLINT type (other integer types may work as well - please test and adjust text):
160166
161167``` SQL
162168CREATE DOMAIN "BOOLEAN"
163169 AS SMALLINT
164170 CHECK (VALUE IS NULL OR VALUE IN (-1,0,1))
165171 /* -1 used for compatibility with FPC SQLDB; 1 is used by many other data access layers */
166172;
167173```
168174
169175Let your field/column use this domain type e.g.
170176
171177``` SQL
172178CREATE TABLE MYTABLE
173179(
174180...
175181 MYBOOLEANCOLUMN "BOOLEAN",
176182);
177183```
178184
179185- Now you can use .AsBoolean for assigning field values etc
180186
181187**To do: verify this works with Lazarus grids etc as well.**
182188
183189### INSERT INTO...RETURNING problems/Cursor is not open
184190
185191= If you try to select SQL (e.g. Query.Open) with SQL like this:
186192
187193``` SQL
188194INSERT INTO PEOPLE (NICKNAME) VALUES ('Superman') RETURNING ID
189195```
190196
191197and get something like this error:
192198
193199```dos
194200Database error: : Fetch :
195201 -Dynamic SQL Error
196202 -SQL error code = -504
197203 -Invalid cursor reference
198204 -Cursor is not open(error code: 335544569)
199205```
200206
201207while running FPC 2.6.0 (which is supplied with Lazarus 1.0) or lower, then you probably ran into an FPC SQLDB parser bug.
202208
203209SQLDB 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.
204210
205211If you're using generators/sequences for your primary keys (like many do), a workaround is to first get the next sequence number:
206212
207213``` SQL
208214SELECT NEXT VALUE FOR GEN_PEOPLEID FROM RDB$DATABASE /* If your generator name is GEN_PEOPLEID */
209215```
210216
211217then use that to do a regular INSERT. see [FAQ entry](http://www.firebirdfaq.org/faq111/%7CFirebird)
212218
213219### Locate does not seem to work
214220
215221Source: [Issue \##21988](https://bugs.freepascal.org/view.php?id=#21988)
216222
217223When running locate on UTF8 (or presumably other multibyte character sets) CHAR fields, locate may not find your record.
218224
219225The 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.
220226
221227Values 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).
222228
223229Workaround: rewrite your select query:
224230
225231``` sql
226232SELECT substring(THEFIELD from 1 for 8) AS THEFIELD ...
227233```
228234
229-`or`
235+```text
236+or
237+```
230238
231239``` sql
232240SELECT cast(THEFIELD as varchar(8)) as THEFIELD ...
233241```
234242
235243or use VARCHAR fields.
236244
237245Note: this problem may occur for other databases as well depending on their reporting of field length.
238246
239247## Advanced transactions
240248
241249Sources for this information/further reading:
242250
243251- [Understanding Firebird Transactions](http://www.ibphoenix.com/resources/documents/how_to/doc_400) very detailed article
244252- [Transactions in Firebird](https://ib-aid.com/en/transactions-in-firebird-acid-isolation-levels-deadlocks-and-update-conflicts-resolution/) another very detailed article
245253- Interbase 6 API Guide (valid for Firebird+Interbase), page 63 and further
246254- [Overview of transaction settings in Interbase](http://conferences.embarcadero.com/article/32280)
247255- [Detailed explanation of parameters in Firebird](http://tech.groups.yahoo.com/group/firebird-support/message/58653)
248256- [Overview of settings in Firebird](http://fhasovic.blogspot.com/2005/02/transaction-isolation-levels-in.html)
249257- [Transaction isolation levels in FIBPlus](http://www.devrace.com/en/fibplus/articles/3292.php)
250258- README.set_transaction.txt in Firebird 2.5 documentation folder.
251259
252260### Transaction isolation levels
253261
254262If you want to, you can change the transaction isolation levels by adding a line in the transaction's Parameters property:
255263
256264- `isc_tpb_read_committed`: you see all changes committed by other transactions
257265- `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.
258266- `isc_tpb_consistency`: also called Table Stability: stable, serializable view of data, but locks tables. Unlikely you will need this
259267
260268Example:
261269
262270``` pascal
263271SQLTransaction1.Params.text:='isc_tpb_read_committed';
264272```
265273
266274You can also add additional parameters that have an effect on the transaction (taken from the ibconnection.pp source file and [1](http://conferences.embarcadero.com/article/32280)):
267275
268276### Access mode
269277
270278This allow reads only or read/write
271279
272280- `isc_tpb_read`: read permission
273281- `isc_tpb_write`: read+write permission
274282
275283### Lock resolution
276284
277285- `isc_tpb_nowait`: if another transaction is editing the record then don't wait
278286- `isc_tpb_wait`: if another transaction is editing the record then wait for it to finish. Can mitigate "live locks" in heavy contention ([2](http://tech.groups.yahoo.com/group/firebird-support/message/58653)). See below for timeout value.
279287
280288### Table reservation
281289
282290Deals with locking entire tables.
283291
284292- `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.
285293- `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
286294- `isc_tpb_lock_read`: Set a read lock. Specify which table to lock, e.g. isc_tpb_lock_read=CUSTOMERS
287295- `isc_tpb_lock_write`: Set a read/write lock. Specify which table to lock, e.g. isc_tpb_lock_read=CUSTOMERS
288296
289297Combinations:
290298
291299- Shared, lock_write: write transactions with concurrency or read committed isolation
292300
293301can update the table. All transactions can read the table
294302
295303- Shared, lock_read: any transaction can read or update
296304- Protected, lock_write: Other transactions cannot update the table. Only concurrency and
297305
298306read committed transactions can read the table
299307
300308- Protected, lock_read: Other transactions cannot update the table. Any transaction can
301309
302310read the table
303311
304312### Record versions
305313
306314This setting is apparently only relevant for isc_tpb_read_committed isolation mode for records being modified by other transactions:
307315
308316- `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)
309317- `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
310318
311319### Various options
312320
313321For 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.
314322
315323- isc_tpb_exclusive (apparently translates to protected in Firebird, see [3](http://tech.groups.yahoo.com/group/firebird-support/message/58653))
316324- isc_tpb_verb_time (Related to deferred constraints, which could execute at verb time or commit time. Firebird: not implemented, always use verb time)
317325- isc_tpb_commit_time (Related to deferred constraints, which could execute at verb time or commit time. Firebird: not implemented, always use verb time)
318326- 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)
319327- isc_tpb_autocommit (autocommit this transaction: every statement is a separate transaction. Probably specifically for JayBird JDBC driver.)
320328- 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.)
321329- 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.)
322330- 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.)
323331
324332### Firebird and ISO transactions
325333
326334Firebird transaction do not map 1 to 1 to ISO/ANSI transaction levels. An approximation is:
327335
328336- ISO Read Committed=READ COMMITTED+RECORD_VERSION
329337- ISO Read Committed=READ COMMITTED+NO RECORD_VERSION
330338- ISO Repeatable Read=SNAPSHOT (also known as CONCURRENCY)
331339- ISO Serializable=SNAPSHOT TABLE STABILITY (also known as CONSISTENCY)
332340
333341### Common combinations
334342
335343Default is (probably, will have to check) read committed.
336344
337345#### Batch/bulk insert
338346
339347isc_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.
340348
341349#### Read only transaction
342350
343351If you want to only have read access to the database, you can do so by setting these transaction parameters:
344352
345353- `isc_tpb_read`
346354- `isc_tpb_read_committed`
347355- `isc_tpb_rec_version`
348356- `nowait`
349357
350358This combination will not block garbage collection, which is a good thing. Source: [4](http://tech.groups.yahoo.com/group/firebird-support/message/118748)
351359
352360Note: the [Firebird FAQ](http://www.firebirdfaq.org/faq164/) 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).
353361
354362## Links and more information
355363
356364The list below shows links to more information on Firebird and related tools.
357365
358366- [[Firebird embedded|Using Firebird embedded with FPC/Lazarus]]
359367
360368### Lazarus Firebird samples
361369
362370- Sample Lazarus/Firebird application source code [5](http://lazarus.freepascal.org/index.php/topic,13940.msg73617.html#msg73617)
363371- Firebird/SQLDB tutorials:
364372 - [[SQLdb Tutorial0]]
365373 - [[SQLdb Tutorial1]]
366374 - [[SQLdb Tutorial2]]
367375 - [[SQLdb Tutorial3]]
368376 - [[SQLdb Tutorial4]]
369377
370378- PP4S tutorials; cover Firebird installation on Windows as well:
371379 - [Planning a Database](http://www.pp4s.co.uk/main/tu-db-plan.html)
372380 - [Installing Firebird](http://www.pp4s.co.uk/main/tu-db-installingfirebird01.html)
373381 - [Creating a Firebird database](http://www.pp4s.co.uk/main/tu-db-firebird-create.html)
374382 - [Editing a Firebird database](http://www.pp4s.co.uk/main/tu-db-firebird-demo1.html)
375383 - [Searching a Firebird database](http://www.pp4s.co.uk/main/tu-db-firebird-demo2.html)
376384 - [Creating and printing a report](http://www.pp4s.co.uk/main/tu-db-firebird-demo3.html)
377385 - [Creating and using stored procedures](http://www.pp4s.co.uk/main/tu-db-firebird-demo4.html)
378386
379387### Tools
380388
381389- FlameRobin [Flamerobin site](http://www.flamerobin.org/) Open source GUI tool to manage Firebird, available for Linux, Windows and Mac OSX. Highly recommended.
382390- Turbobird [Turbobird site](https://github.com/motaz/turbobird) Open source GUI tool to manage Firebird. Written with Lazarus using TIBConnection
383391- ibconsole : Tool to manage Firebird an Interbase Databases with a GUI, available for Windows and Linux
384392- Lazarus Data Desktop - included in the Lazarus repository (found in the 'tools/lazdatadesktop/' directory)
385393- [LazSQLX](http://lazsqlx.wordpress.com/) Multi-database open source database management tool. Written with Lazarus using both SQLDB and Zeos components. Includes support for Firebird.
386394- 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.
387395
388396### Firebird
389397
390398- The Firebird RDBMS [Firebird site](http://firebirdsql.org/). This site also contains a lot of documentation on Firebird.
391399- Firebird FAQ [6](http://firebirdfaq.org/). Handy site that shows e.g. differences with other RDBMS.
392400- New site that shows how to use the latest tools and LibreOffice, FPC to be added soon [Firebird](http://www.controlpascal.com/firebird.htm)
393401
394402---
395403*From the Free Pascal wiki, page "Firebird", 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](/wiki-contact).*

Back to history