Sign in Join
Wiki copytemporary

Revision 3 of 3, by WikiArchive on 11-10-2026. The page as it is now.

Databases/zh CN


Databases portal
References: · General info · Libraries · Field types · Controls · FAQ · SQL how-to · Working With TSQLQuery · In-memory database applications · Tutorials/practical articles: · Overview · 0 - Database set-up · 1 - Getting started · 2 - Editing · 3 - Queries · 4 - Data modules · SQLdb Programming Reference · Databases · Advantage - MySQL - MSSQL - Postgres - Interbase - Firebird - Oracle - ODBC - Paradox - SQLite - dBASE - MS Access - Zeos

本文介绍了Lazarus和数据库 。下表给出了 Lazarus 支持的数据库。

请只安装必要的数据库组件,如数据库需用到客户端库则应先安装客户端库。否则由于缺少文件,Lazarus 可能会无法启动。因为数据库组件无法卸载,一旦有问题 Lazarus 就得重装。

支持的数据库

数据库 软件包名 是否需要客户端库 是否需要服务器端 支持的版本 支持的平台
Advantage TAdsDataSet 是 否 10.1 以上 i386: Linux、Win32
DBase DBFLaz 否 否 III+, IV, VII 所有
TurboPower FlashFiler FlashFiler 否 否 - Win 32、(win64?)
In memory memds 否 否 - 所有
In memory bufdataset 否 否 - 所有
Firebird SQLdb 是 依赖于1 1 - 2.5 i386: Linux、Win32
(Visual) FoxPro DBFLaz 否 否 2.0, 2.5, 3.0 (不完全) 所有
Interbase SQLdb 是 是 4 - 6 i386: Linux、Win32
Microsoft SQL Server SQLdb 是 是 6- FPC 2.6.2+. Linux、macOS、Win32、可能 *BSD、可能 Solaris2
MySQL SQLdb 是 是 3.0 - 5.5 i386: Linux、Win32
ODBC SQLdb 是 有依赖条件 3.x 3 i386: Linux、Win32
Oracle SQLdb 是 是 - -
Paradox TParadoxDataSet 否 否 最高至7级表(以上?) 所有
Paradox TParadox 是 否 Win32
PostgreSQL SQLdb 是 是 6.6 - 8 i386: Linux、Win32
Sybase Adaptive Server Enterprise (ASE) SQLdb 是 是 任何 Linux、macOS、Win32、可能 *BSD, 可能Solaris2)
SQLite SQLdb 是 否 sqlite3 所有
SQLite SQLite(3)Laz 是 否 sqlite2、sqlite3 所有
Text 文件 sdf 否 否 - 所有
ZMSQL zmsql 否 否 ? ?

注1: 可在 Windows 和 Linux(可能也包括 macOS)中使用嵌入版的 Firebird,或者连到运行于 Windows/Unix/macOS/FreeBSD/其他 Firebird 支持平台中的 Firebird 服务器。

注2: 这些连接库用 FreeTDS 作为驱动程序,FreeTDS 的文档指出,至少应该可在这些平台下编译。Windows x86/x64 版本可在此下载:1(ftp://ftp.freepascal.org/fpc/contrib/windows/dblib_x32.zip) 和 2(ftp://ftp.freepascal.org/fpc/contrib/windows/dblib_x64.zip)

注3: 这里是指 ODBC 标准的版本,而非驱动程序或驱动程序管理器的版本号。大多数 DBMS 都带有 ODBC 3.x 驱动程序。

绑定数据库客户端

如果连接数据库需要客户端库,那就必须安装一下。不仅要在编程的计算机上安装,还要在所有运行应用程序的计算机上安装。请注意,某些数据库(特别是 MySQL)要求,编译时绑定的库版本必须与安装运行时的相同。在数据库开发方网站上,可以找到客户端库的安装方法(在 *nix 系统上是 .so 文件,在 Windows 上是 .dll 文件)。有关绑定的代码文件位于 fpc-sources 的 packages/base 目录中。内容基本就是一些客户端 API 的调用,比如 mysql_connect_database,每种数据库的调用各不相同。当然可以用这些代码文件编写数据库应用,但通常会增加很多工作量,且更容易出错,相比之下,使用 Lazarus 的 DB 组件会更为方便。

这些绑定软件包大多用硬编码链接客户端库。这意味着,如果在编译时包含了某个单元,但没有合适的客户端库,那么整个应用程序将无法链接。也就是说,如果计算机中没有安装 MySQL 客户端,程序中又使用了 mysql4.pp 单元,那么将无法生成可执行文件。虽然在安装了 MySQL 客户端库的计算机上编译成功,但在没有对应 MySQL 客户端库的其他机器上该程序仍然无法启动。换句话说:这些数据库要在开发机器上安装客户端库,并且还要将这些客户端库与应用程序一起安装。

为了避免这类问题,有些包能够动态链接到客户端库。在调用客户端库之前,必须先进行“初始化”。如果计算机上没有安装数据库客户端,初始化就会失败。如果客户端库连接就绪,那么之后需要执行“释放”操作。

数据集

数据集和数据库的区别

许多数据库编程新人无法区分数据集和数据库。现在数据库有很多种,比如 Firebird、Interbase、Oracle、Sybase、Microsoft Access 等。

最简单的概念就是,Lazarus 数据集(TDataset 的子类,如 TSQLQuery 等)可视为部分数据库查询记录的副本。假设用以下 SQL 语句打开查询:

pascal
SQLQuery1.SQL.Text:= 'select * from table1 where id <=100';

打开 SQLQuery1,数据库 table1 中 id 小于等于 100 的记录将复制到 SQLQuery1 中。

通过 TDatasource(其又与 TDataset 连接),数据集中的数据可用数据库控件(如 TDBGrid、TDBEdit 等)进行可视化展示。

数据集中的数据可通过 insert、edit、delete、post 等命令(后续会讲解)进行修改,但这些操作都是基于数据集进行的,而不是直接在数据库表上完成。需要多做一步才能让改动持久性地存入数据库,比如调用 TDataSet.ApplyUpdates 或执行插入、更新 SQL 语句(与 TDataset.insert 或 TDataset.update 不同)。

通过设置数据库的事务属性,可在数据集关闭时将改动自动保存(或丢弃)。

数据集简介

在 Lazarus(或 Free Pascal)中,数据库的使用底层都基于 TDataSet 类展开。在应用程序中,TDataSet 类代表一张表或一个查询。然而,与很多其他基础类一样,TDataset 类不会直接用到,而会采用其某个子类。这些子类有很多,提供了对各种数据库的访问,例如本地 dBase 或文本文件,或者远程数据库如 PostgreSQL、Firebird、MySQL等。有些子类直接链接到数据库表,而另一些则使用其他组件或库来执行链接。

Dataset 的子类是非可视化组件,通常属于自由组件库(FCL)而不是 Lazarus 组件库(LCL)。

数据集既可通过纯代码方式使用,也可与可视化控件一起使用。典型的 Lazarus 数据库应用通常会同时使用这两种方式。不论哪种方式,第一步都是创建 TDataset 子类,进行初始化以连接到所需的表或查询,并执行 open 操作。可在运行时用代码完成,也可通过在窗体上放置组件并在设计时设置属性来完成。不同的 TDataset 子类在这方面的细节差异很大,因此请参阅数据库中的各个手册,了解操作步骤。

数据集打开后,会创建一些字段组件,每个字段(或打开的表、查询的列)都对应一个字段组件。每个字段组件都是 TField 的子类,根据字段的数据类型(如 TStringField)对应某个子类。

通过代码使用数据集对象

关于以编程方式访问数据集对象的详细说明,请参阅数据集和字段组件的用法,不过以下给出了非常简单的描述:

字段类型的清单参见 Database field type。

可视化(数据感知)控件的用法

若要在简单的“RAD”风格的 Lazarus 应用中使用数据库,通常会在设计时配置数据集子类,然后使用数据感知控件。这需要:

更多有关控件的信息,请参阅下文中的 #Data Controls。

数据集的状态

数据集可能处于多个状态。状态虽有很多(可以在源代码中查找 TDataSetState),但初学者需要了解的状态主要有:

状态 功能
dsInactive 已关闭
dsBrowse 用户可浏览,查看数据值
dsEdit 用户可编辑当前行的数据值。在执行 post 前不会保存。
dsInsert 加入新行,用户可设置值。在执行 post 前此行不会保存。

其他状态相对短暂,并且通常会“自动”处理,用于内部和更复杂的代码。如果只是查看数据库中的数据,并且在设计时打开数据集,那么很大程度上可以忽略状态的概念,因为大部分时间都会处于 dsBrowse 状态。不过大多数应用都需要修改数据。如果采用数据感知控件,则很多操作都会自动处理。例如TDBEdit控件在修改文本时,会将数据集置于 dsEdit 状态——除非原来就已处于 dsEdit 或 dsInsert 状态。如果在 dsEdit 或 dsInsert 状态时“滚动”到其他记录去,那么当前编辑的记录将被“提交”,数据集将回到 dsBrowse 状态。但如果是用代码访问数据集,那通常就必须用代码修改状态了。TDBNavigator控件(见下文)允许用户显式修改状态。

数据集的 UpdateStatus 属性

如果更新操作尚未写入数据库,UpdateStatus 标识了数据记录缓冲区的当前状态。

示例 如何检测 ApplyUpdates 要执行插入、更新还是删除操作:

pascal
procedure QueryAfterPost(DataSet: TDataSet);
    begin
      case DataSet.UpdateStatus of
        usUnmodified : ShowMessage('Unmodified');
        usModified   : ShowMessage('Modified');
        usInserted   : ShowMessage('Inserted');
        usDeleted    : ShowMessage('Deleted');
      end;
    end;

解释

提交和撤销

如果记录已完成编辑和插入,新值将保存在缓冲区中。

插入新记录

要通过 TDataSet 子类插入新记录,应该使用 Insert 方法。先要设置字段值,最后再调用 Post 提交新记录,如下所示。

以下例子还展示了如何将文件数据插入 BLOB,也可以用 LoadFromStream 从流中加载数据。

pascal
MyDataset.Insert;
      MyDataset.Fields[0].AsInteger := 4; //整数字段
      MyDataset.Fields[1].AsString := 'First Name'; //字符串字段
      (MyDataset.Fields[2] as TBlobField).LoadFromFile('SomeBlobfile.bin'); //blob 字段
      MyDataset.Post;

快速跳转至表中某条记录

已查出所有记录

如果是用 SELECT * FROM 查出了表中所有记录,然后要在记录之间快速跳转,那么就得先建索引再检索。更高效的做法是只查询需要的记录。

只查询所需记录

跳转至某条记录的一种做法,就是只查询这条记录,例如:

pascal
var
      MyDataset: TSQLQuery;
    begin
      //...
      MyDataset.FieldDefs.Add('SessionId', ftLargeint);
      MyDataset.FieldDefs.Add('GameEvent', ftLargeint);
      MyDataset.FieldDefs.Add('TableId', ftInteger);
      MyDataset.FieldDefs.Add('LoggedIn', ftBoolean);
      MyDataset.FieldDefs.Add('PlayerId', ftInteger);
      MyDataset.Active := False;
      { Non-parameterized format; may run into issues with text containing ' and dates
      SQLText := Format('select * from "GameSession" WHERE "SessionId"=%d', [ASessionId]);
      }
      // 解决方案:带参数的查询
      // 如果是在循环中,其实 SQL.Text 只需设置一次,后续只要修改参数值即可。
      MyDataset.SQL.Text := 'select * from "GameSession" WHERE "SessionID"=:SessionID');
      MyDataSet.ParamByName('SessionID').AsLargeInt := ASessionID;
      try
        MyDataset.Active := True;
      except
        //...
      end;

然后可以读取数据如下:

pascal
lPlayerId := MyDataset.Fields[4].AsInteger;

数据过滤

过滤操作可将数据集限制为所需子集(比如所有以 Smith 开头的姓氏)。

locate/lookup 方法

locate/lookup 可用于在记录之间跳转,但更多是在非SQL数据集中使用(如TParadoxDataSet、TDbf)。

TSQLQuery 用法

TSQLQuery 详见 Working With TSQLQuery。

数据导出

FPC/Lazarus 提供了将数据集以多种格式导出的工具包:

当然,也可以手动导出(比如用 fpspreadsheet 导出为 Excel 格式的 FPSpreadsheet#Converting_a_database_to_a_spreadsheet)。

Data Controls 控件组

使用这些控件需先加到窗体中,并至少应设置 datasource 属性。下面会介绍其他的关键属性。

Datasource 控件

此控件用于跟踪所关联控件当前位于哪条记录。Datasource 控件必须关联某个数据集控件(如 TSQLQuery)。

单字段控件

这些控件都是用于关联单个字段。除了设置 Datasource 外,还需设置字段名称。包括了:

DBGrid 控件

此控件以行/列布局的形式显示多个字段——其实默认显示所有字段。但可在列集合中添加字段项,以便仅显示指定字段并设置列宽和标题。

除 DBGrid 文档 之外,Grids Reference Page#TCustomDBGrid 也包含更多信息。

TBNavigator 控件

此控件能让用户更直接地控制数据集。可以:

主要属性:

FPC 数据库应用的测试

Free Pascal 数据库组件包含了一个基于 fpcunit 的代码测试框架 dbtestframework,可用于验证代码的功能是否正常。 参见 FPC 源码目录 source\packages\fcl-db\tests\。 Included 是个可运行各种数据库组件的测试框架,还包含了一些其他测试(比如数据库输出)。

请按以下步骤配置数据库并运行测试框架:

1. 将 source\packages\fcl-db\tests\database.ini.txt 保存为 source\packages\fcl-db\tests\database.ini

2. 修改 source\packages\fcl-db\tests\database.ini ,选取所需的数据库类型。

连接 Interbase/Firebird 数据库的示例:

pascal
[Database]
    type=interbase

3. 在同一个文件中配置数据库参数。比如上面选的 Interbase:

pascal
[interbase]
    connector=sql
    connectorparams=interbase
    ; Database name/path (note: database needs to exist already)
    ; You can use aliases (see aliases.conf in your Firebird documentation)
    name=testdb
    user=sysdba
    password=masterkey
    ; your hostname may very well differ:
    ; Leave blank if you want to use an embedded Firebird database
    hostname=192.168.0.42

4. 编译运行 source\packages\fcl-db\tests\dbtestframework.pas (也可用 Lazarus 编译运行 GUI 版的代码 dbtestframework_gui) 若是在 Windows 中使用嵌入式数据库(如 Firebird 嵌入版或 sqlite),请先将所需的 DLL 文件复制到程序所在目录中。输出结果是 XML 格式(dbtestframework_gui 则会显示在屏幕上)。

更多详情请参阅 source\packages\fcl-db\tests\README.txt。

Lazarus 提供的数据库软件包

sqldblaz.lpk

sqldbcomponents.png

用于访问多种数据库,包括:

所有组件(TSQLQuery、TSQLTransaction、TIBConnection、TODBCConnection、TOracleConnection、TMSSQLConnection、TMySQL40Connection、TMySQL41Connection、TMySQL50Connection、TPQConnection、TSybaseConnection)均位于组件面板的 SQLdb 页。

dbflaz.lpk

用于访问 dBase 和 FoxPro 数据库。详见 Lazarus Tdbf 教程。TDbf 组件位于组件面板的 Data Access 页。

sqlitelaz.lpk

用于访问 SQLite 数据库。详见 Lazarus 数据库开发概述。

sdflaz.lpk

TSdfDataSet 位于组件面板的 Data Access 页。

lazreport.lpk

报告生成器的项目主页位于 http://lazreport.sourceforge.net/。 更多信息(其他链接)详见这里。 LazReport 依赖 Printer4Lazarus 包。 Lazarus SVN 仓库纳入了 LazReport 11950 修订版。

lazdbexport.lpk

参见 lazdbexport。

外部软件包/库

Zeos DataBase Objects

这些组件用于访问各种数据库。更多信息请参阅此处,自带 Zeos 教程。

Pascal Data Objects

已有替代品。

支持:

数据库 API Pascal Data Objects 支持预编译语句、绑定和存储过程等功能,设计灵感来自 PHP Data Objects。所有代码和文档均在 Sourceforge: http://pdo.sourceforge.net

TPSQL

通过 TCP/IP 访问 PostgreSQL 数据库。详见 TPSQL。

FIBL

用于访问 Interbase 和 Firebird 数据库。主页为 3(http://sourceforge.net/projects/fibl)。

IBX

用于访问 Firebird 数据库,参见IBX。

FBLib Firebird Library

FBLib 是个开源库,无数据感知能力,用于 Borland Delphi/Kylix、Free Pascal 和 Lazarus 直接访问 Firebird 关系数据库。

目前支持以下特性:

文档见 FBLib 网站。

Unified Interbase

UIB 支持访问 Interbase、Firebird 和 YAFFIL 数据库。主页为 [www.progdigy.com](http://www.progdigy.com)。svn 仓库 https://uib.svn.sourceforge.net/svnroot/uib。

TechInsite Object 持久化框架 (tiOPF)

详见 tiOPF。

访问 Advantage 的 TDataSet 子类

Advantage TDataSet 子类可用于连接 Advantage 数据库服务器(访问表)。Advantage 是一种灵活的、无需管理的嵌入式数据库,支持客户端/服务器或点对点方式访问 Clipper、FoxPro 和 Visual FoxPro 9 的 DBF 文件格式,同时还支持一种专有文件格式并提供迁移方案,以便用户能应用新特性。

主要特性:

更多信息,请参阅网站 Advantage Database Server。

ZMSQL:增强型 SQL 内存数据库

更多信息,请参阅 ZMSQL wiki。

ZMSQL 是开源的、基于 TBufDataset 子类的增强型 SQL 内存数据库,专为 Free Pascal(FPC)设计,基于分号分隔的文本表进行操作。ZMSQL 完全用 Pascal 语言编写,不依赖任何外部库,SQL 功能用 JanSQL 引擎实现。

支持以下特性:

可下载的内容包括了源代码、演示应用(用于说明组件的功能)和自述文件。

参阅


From the Free Pascal wiki, page "Databases/zh CN", as the Internet Archive kept it on 2025-02-17, last changed on 2024-12-30. 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.