百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

「11.Lazarus数据库编程」5.Lazarus和FireBird embedded

ztj100 2024-11-23 00:03 54 浏览 0 评论

5.Lazarus 和 FireBird embedded

5.1 Firebird embedded

【以下内容翻译自官网】

https://wiki.freepascal.org/Firebird_embedded

什么是 Firebird Embedded

Firebird Embedded 是 Firebird 数据库服务器的特殊版本。它允许您在没有专用数据库服务器的情况下运行程序。相反,您将一个库 (DLL/.so/.dylib) 添加到您的应用程序中并让您的应用程序使用该库访问您的 Firebird .fdb 数据库文件。这类似于 Microsoft Access 和 LibreOffice Base 等程序的工作方式。

优点

  • 在许多架构上运行(Linux、macOS、Windows、FreeBSD、Solaris)
  • 无需单独的服务器设置,降低复杂性
  • 您可以轻松地从嵌入式切换到完整的客户端/服务器 - 无需更改一行代码(连接字符串除外)。与 sqlite 相比,这可能是一个不错的优势。

缺点

  • 仅单用户访问
  • 分发时需要与您的程序一起分发一些库(除非您可以静态链接它们)

安装

在 Windows 上,Firebird 嵌入式和常规 Firebird 客户端库是不同的文件。Firebird Embedded 始终可以用作常规客户端,使其成为您安装中的合理选择。

Windows

下载并解压缩 Firebird 嵌入式套件。确保 .dll 和 .manifest 文件是:

  • 在您的项目目录和可执行输出目录(生成 .exe 的位置)或
  • 在 PATH 中的目录中(不是系统目录)(如果您不想继续复制 dll,则很有用)

请注意,位数必须匹配:如果您为 64 位编译程序,则必须使用 64 位嵌入式版本,如果您正在编写 32 位程序,则必须使用 32。还要确保将 .dlls 和 .manifest 文件放置在您的项目输出(可执行)目录中,并将它们与您的应用程序以及许可证文件一起分发。

作为指示,Firebird 2.5 的最低必要文件是:

fbembed.dll
firebird.msg
ib_util.dll
icudt30.dll
icuin30.dll
icuuc30.dll
IDPLicense.txt
IPLicense.txt
Microsoft.VC80.CRT.manifest
msvcp80.dll
msvcr80.dll

Linux

对于 Debian,可能与 Ubuntu 类似:

获取库文件以及符号链接:例如 /usr/lib/x86_64-linux-gnu/libfbembed.so 链接到 /user/lib/x86_64-linux-gnu/libfbembed.so.bla.xy

aptitude install libfbembed2.5 firebird-dev

至少对于 Firebird 2.5+:不要指定用户名或密码,因为这将强制查找 security.fdb,如果无法访问系统范围的 security.fdb,则可能会失败。请在 Firebird 2.5+ 上指定角色 RDB$ADMIN,因为这应该让您完全控制数据库文件。

将这些文件放在您的项目目录中(要做:测试是否都需要):

firebird/libfbembed.so (or perhaps libfbembed.so.2.5)
firebird.conf
firebird/security.fdb #perhaps not necessary
firebird/intl/fbintl
firebird/udf/fbudf.so

对于 Firebird 3,您将需要:

firebird/libfbclient.so
plugins/libEngine12.so

您需要更改插件目录变量。如果你不能这样做,你需要将 libEngine 放到它的原始目录中。

已经在 firebird.conf 中设置了这个(要做:检查这是否都需要)

RootDirectory=./firebird #replace with your directory
DatabaseAccess = Full #probably useful
ExternalFileAccess = Full #probably useful
UdfAccess = Full #probably useful
#disable
#TempDirectories = /tmp #=> didn't fix /tmp/firebird lock issues
#TempDirectories = ~/tmp #=> didn't fix /tmp/firebird lock issues

应用程序启动前需要设置两个环境变量。假设应用程序安装在 /home/pascaldev/embed 中:

# tell dynamic loader where to find embedded lib:
LD_LIBRARY_PATH=/home/pascaldev/embed/firebird
# tell server where to find files (messages, config etc)
FIREBIRD=. #or use absolute path: /home/pascaldev/embed

如果您遇到错误,例如

EIBDatabaseError/ : DoInternalConnect :
 -Can't access lock files' directory /tmp/firebird

您可能有其他用户拥有的陈旧锁定文件删除 /tmp/firebird 目录有效,但问题是它将在您自己的本地权限下重新创建

连接到 Firebird 服务器

如前所述,嵌入式 Firebird 可以像普通的 Firebird 客户端一样工作。因此,使用嵌入式 Firebird 库而不是客户端/服务器 Firebird 库可以帮助您的应用程序更加灵活。

注意:至少在 Firebird 嵌入式 2.5.3 和 FPC 2.6.4 中存在一个错误,在关闭与远程服务器的连接时会崩溃。此错误已在 FPC 中继中修复。

使用

一旦您在正确的路径中拥有了正确的 Firebird 嵌入式库(见上文),您需要指定您连接到嵌入式而不是客户端服务器环境。将 IBConnection 对象的主机名属性留空。其余属性的工作方式与客户端/服务器版本类似,例如 DatabaseName 是您的 .fdb 文件的完整路径,如果它与 fbembed.dll 位于同一目录中,则只是数据库名称。此外,旧版本的 FPC(FPC 2.6.2+ 当然不需要这个)可能需要您将UseEmbeddedFirebird属性设置为 true。SQLDB 单元中不存在该属性,但您需要将 ibase60dyn 添加到您的 uses 子句中。

创建数据库

使用 Firebird ISQL

您可以使用 Firebird isql 应用程序创建数据库(例如,在常规 Firebird(客户端)包中提供)。在 Windows 上,此可执行文件应与 fbembed.dll 位于同一目录中。注意:isql 需要 fbclient 库,而不是 fbembed;您可以复制并重命名 fbembed,例如 Windows 上的 fbclient.dll,以解决此问题。运行isql,然后执行:

create database 'employee.fdb' user 'SYSDBA' password 'masterkey' page_size 16384 default character set UTF8;
exit;

删除数据库基本上意味着删除文件,但您也可以运行: isql

connect 'employee.fdb' user 'sysdba' password 'masterkey';
drop database;
commit;
exit;

以编程方式创建数据库

您还可以在程序中创建数据库。下面创建测试数据库部分中的程序显示了如何检测丢失的数据库并动态创建它们。在初始化表单(FormShow 事件)时,可以在 Lazarus 应用程序中调用类似的过程。

创建表、视图、触发器等对象...

在 Firebird 和 Firebird 嵌入式中创建对象,与大多数事情一样是相同的。

手动创建数据库

isql

create database 'test.fdb' user 'SYSDBA' password 'masterkey' page_size 16384 default character set UTF8;
exit;

以编程方式创建数据库

您可以以编程方式创建数据库。下面的示例创建了一个本地的嵌入式数据库,但可以轻松地将其更改为远程数据库(调整主机名和必要时的路径):

program firebirdembeddedtest;
{$mode objfpc}{$H+}

uses 
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF} 
  Classes, SysUtils,
  sqldb, IBConnection {for Firebird};

const
  // Name for the database. Be sure to specify the same name in your database.ini
  DatabaseFile = 'test.fdb'; //Sensible name for a test database, right?
var
  Fire: TIBConnection;

begin
  //Connection to Firebird database
  // The next line is needed for quite old FPC versions
  // Newer versions will first look for fbembed.dll in the application directory automatically
  //UseEmbeddedFirebird:=true; // Using embedded (and fbembed.dll) or regular client/server (fbclient.dll), requires ibase60dyn in uses
  Fire:=TIBConnection.Create(nil);
  try
    Fire.HostName := ''; //must be empty for embedded Firebird; must be filled for client/server Firebird
    Fire.DatabaseName := DatabaseFile; //(path and) filename
    // Username and password do not matter for authentication, but you do get authorizations in the database
    // based on the name (and optionally role) you give.
    Fire.Username := 'SYSDBA';
    Fire.Password := 'masterkey'; //default password for SYSDBA
    Fire.Charset := 'UTF8'; //Send and receive string data in UTF8 encoding
    Fire.Dialect := 3; //Nobody uses 1 or 2 anymore.
    Fire.Params.Add('PAGE_SIZE=16384'); //I like a large page size (used when creating a database). Useful for larger indexes=>larger possible column sizes

    // Find out if there is a database in the application directory.
    // If not, create it. Note: this may fail if you don't have enough permissions.

    // If you use client/server, you obviously don't need this part of the code.
    if (FileExists(DatabaseFile)=false) then
    begin
        writeln('File '+DatabaseFile+' does not exist.');
        writeln('Creating a Firebird embedded database...');
        // Create the database as it doesn't exist
        try
          Fire.CreateDB; //Create the database file.
        except
          on E: Exception do
          begin
            writeln('ERROR creating database. Probably problems loading embedded library:');
            writeln('- not all files present');
            writeln('- wrong architecture (e.g. 32 bit instead of 64 bit)');
            writeln('Exception message:');
            writeln(E.ClassName+'/'+E.Message);
          end;
        end;
        Fire.Close;
    end;
  finally
    Fire.Free;
  end; 
end.

5.2 使用 FireBird Embedded 进行数据库开发

1.在 Lazarus 环境下创建一个应用

2.将 FireBird Embedded 数据库解压缩到某个目录,我采用的是:

Firebird-2.5.9.27139-0_x64_embed.zip

解压缩后的文件如下图所示:

3.将如下文件复制到 Lazarus 应用所在目录

fbembed.dll
firebird.msg
ib_util.dll
icudt30.dll
icuin30.dll
icuuc30.dll
IDPLicense.txt
IPLicense.txt
Microsoft.VC80.CRT.manifest
msvcp80.dll
msvcr80.dll

4.将同版本号的 FireBird C/S 版本的 isql.exe 文件复制到Lazarus 应用所在目录,我采用的是:

Firebird-2.5.9.27139-0_x64.zip

5.复制 fbembed.dll 文件并重命名为 fbclient.dll

6.在 cmd 命令提示符下执行:

> cd <Lazarus 应用所在目录>
> isql
Use CONNECT or CREATE DATABASE to specify a database
SQL>

说明 FireBird Embedded 安装成功

7.通过 SQL 命令创建数据库

SQL> create database 'test.fdb' user 'SYSDBA' password 'admin' page_size 16384 default character set UTF8;
SQL>

8.创建数据表

SQL> create table d_students1 (
CON>    student_id varchar(64) primary key,
CON>    name varchar(16),
CON>    sex varchar(8),
CON>    birthday date,
CON>    department_id integer,
CON>    total_score decimal(9,1)
CON> );

9.插入数据

SQL> INSERT INTO d_students1
CON> (student_id, name, sex, birthday, department_id, total_score)
CON> VALUES('x-20210001', 'ZhangSan', 'Man', '2000-05-06', 1, 520);
SQL> INSERT INTO d_students1
CON> (student_id, name, sex, birthday, department_id, total_score)
CON> VALUES('x-20210002', 'LiSi', 'Man', '2000-03-09', 1, 539);
SQL> INSERT INTO d_students1
CON> (student_id, name, sex, birthday, department_id, total_score)
CON> VALUES('x-20210003', 'ZhouWu', 'Woman', '2001-09-10', 2, 528);
SQL> INSERT INTO d_students1
CON> (student_id, name, sex, birthday, department_id, total_score)
CON> VALUES('x-20210004', 'ZhaoLiu', 'Woman', '2000-08-28', 1, 517);
SQL> INSERT INTO d_students1
CON> (student_id, name, sex, birthday, department_id, total_score)
CON> VALUES('x-20210005', 'JiangQi', 'Woman', '2000-07-06', 2, 547);
SQL> INSERT INTO d_students1
CON> (student_id, name, sex, birthday, department_id, total_score)
CON> VALUES('x-20210006', 'HeBa', 'Man', '2000-11-01', 2, 533);

数据中没有使用中文,原因是使用 UTF8 字符集创建数据库,而 Windows 的命令提示符使用默认的字符集 GBK,互相之间不兼容。

5.3 在应用程序中显示数据

应用程序中使用的组件:

  • TIBConnection
  • TSQLTransaction
  • TSQLQuery
  • TDataSource
  • TDBGrid

在窗体上拖放以上组件,如下图所示:

组件属性设置如下:

组件

属性

IBConnection1

DatabaseName

E:\workspace_of_lazarus\laz1104\TEST.FDB


UserName

sysdba


Password

admin


Transaction

SQLTransaction1


Connected

True


KeepConnection

True


LoginPrompt

False

SQLTransaction1

Database

IBConnection1


Active

True

SQLQuery1

Database

IBConnection1


Transaction

SQLTransaction1


SQL

select * from d_students1


Active

True

DataSource1

DataSet

SQLQuery1

DBGrid1

DataSource

DataSource1


Align

alClient


Options

dgRowSelect=True

【备注】

当设置 IBConnection1 的 Connected 属性为 True,可能会出现不能正常连接数据库的情况,原因是没有使用 fbembed.dll 库连接,如果本机上同时安装了 FireBird C/S 版,则可能会使用 C/S 版的类库进行连接,此时关闭 Lazarus,打开命令行工具,执行如下命令:

set PATH=<Lazarus应用程序所在目录>  本例为:E:\workspace_of_lazarus\laz1104
cd <Lazarus安装目录>
lazarus

Lazarus 启动后再去连接数据库,即设置 IBConnection1 的 Connected 属性为 True。

按下 F9,运行程序,效果如下图所示:

相关推荐

WPS 隐藏黑科技!OCT2HEX 函数用法全攻略,数据转换不再愁

WPS隐藏黑科技!OCT2HEX函数用法全攻略,数据转换不再愁在WPS表格的强大函数库中,OCT2HEX函数堪称数据进制转换的“魔法钥匙”。无论是程序员处理代码数据,还是工程师进行电路设计...

WPS 表格隐藏神器!LEFTB 函数让文本处理更高效

WPS表格隐藏神器!LEFTB函数让文本处理更高效在职场办公和日常数据处理中,WPS表格堪称我们的得力助手,而其中丰富多样的函数更是提升效率的关键。今天,要为大家介绍一个“宝藏函数”——LEF...

Java lombok 使用教程(lombok.jar idea)

简介Lombok是...

PART 48: 万能结果自定义,SWITCH函数!

公式解析SWITCH:根据值列表计算表达式并返回与第一个匹配值对应的结果。如果没有匹配项,则返回可选默认值用法解析1:评级=SWITCH(TRUE,C2>=90,"优秀",C2...

Excel 必备if函数使用方法详解(excel表if函数使用)

excel表格if函数使用方法介绍打开Excel,在想输出数据的单元格点击工具栏上的“公式”--“插入函数”--“IF”,然后点击确定。...

Jetty使用场景(jetty入门)

Jetty作为一款高性能、轻量级的嵌入式Web服务器和Servlet容器,其核心优势在于模块化设计、快速启动、低资源消耗...

【Java教程】基础语法到高级特性(java语言高级特性)

Java作为一门面向对象的编程语言,拥有清晰规范的语法体系。本文将系统性地介绍Java的核心语法特性,帮助开发者全面掌握Java编程基础。...

WPS里这个EVEN 函数,90%的人都没用过!

一、开篇引入在日常工作中,我们常常会与各种数据打交道。比如,在统计员工绩效时,需要对绩效分数进行一系列处理;在计算销售数据时,可能要对销售额进行特定的运算。这些看似简单的数据处理任务,实则隐藏着许多技...

64 AI助力Excel,查函数查用法简单方便

在excel表格当中接入ai之后会是一种什么样的使用体验?今天就跟大家一起来分享一下小程序商店的下一步重大的版本更新。下一个版本将会加入ai功能,接下来会跟大家演示一下基础的用法。ai功能规划的是有三...

python入门到脱坑 函数—函数的调用

Python函数调用详解函数调用是Python编程中最基础也是最重要的操作之一。下面我将详细介绍Python中函数调用的各种方式和注意事项。...

Excel自定义函数:满足特定需求的灵活工具

...

从简到繁,一文说清vlookup函数的常见用法

VLOOKUP函数是Excel中常用的查找与引用函数,用于在表格中按列查找数据。本文将从简单到复杂,逐步讲解VLOOKUP的用法、语法、应用场景及注意事项。一、VLOOKUP基础:快速入门1.什么是...

Java新特性:Lambda表达式(java lambda表达式的3种简写方式)

1、Lambda表达式概述1.1、Lambda表达式的简介Lambda表达式(Lambdaexpression),也可称为闭包(Closure),是Java(SE)8中一个重要的新特性。Lam...

WPS 冷门却超实用!ODD 函数用法大揭秘,轻松解决数据处理难题

WPS冷门却超实用!ODD函数用法大揭秘,轻松解决数据处理难题在WPS表格庞大的函数家族里,有一些函数虽然不像SUM、VLOOKUP那样广为人知,却在特定场景下能发挥出令人惊叹的作用,OD...

Python 函数式编程的 8 大核心技巧,不允许你还不会

函数式编程是一种强调使用纯函数、避免共享状态和可变数据的编程范式。Python虽然不是纯函数式语言,但提供了丰富的函数式编程特性。以下是Python函数式编程的8个核心技巧:...

取消回复欢迎 发表评论: