Sign in Join
Wiki copytemporary

SQLite/zh CN: what changed

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

OldNewLine
11## SQLite 和 FPC/Lazarus 支持
22
33SQLite 是一个嵌入式的 (非服务器的) 、单用户的、可以在 FPC 和 Lazarus 应用程序中使用的数据库。许多驱动可以用于在FPC/Lazarus程序中访问SQLite数据库。 所有的驱动都需要SQLite库/dll在可执行目录(可以是你的项目目录,或者例如 (projectdir)/lib/architecture/ ,这取决于你的Lazarus项目设置)(并与你的可执行文件一起发行)以正常运作。
44
55这可能也需要悲包含在你的 Lazarus IDE 目录. 详见 [1](https://forum.lazarus.freepascal.org/index.php?topic=46118.msg327940#msg327940) 并继续阅读 TSQLite3Dataset 和 TSQLiteDataset See below
66
77大多数 Linux发行版默认安装有 sqlite3 (例如 libsqlite3.so.0),但至少基于Debian的发行版也需要匹配的Dev包才能获得 libsqlite3.so。两者都应通过系统包管理器安装并标记为依赖项,而不是与应用程序一起分发。
88
99Win64: 请看 [[Windows Programming Tips|这里]] 关于不使用某些 FPC/Lazarus Win64 版本的警告
1010
1111### 直接访问 SQLite
1212
1313你可以使用一种简单的方式在 Lazarus 上连接到 SQLite。名为 LiteDAC 的组件。SQLite 数据访问组件(LiteDAC)是一个提供原生的SQLite连接的组件库,在 Windows, macOS, iOS, Android, Linux 和 FreeBSD 的32位及64位上的的Lazarus(和 Free Pascal)。LiteDAC 为编程者开发真正跨平台的桌面和移动的 SQLite 数据库应用程序而无需部署其它额外的库而设计。
1414
1515你可以在这里下载一份这个商业产品的适用版本 Lazarus components.
1616
1717### 内建的 SQLDB
1818
1919FPC/Lazarus 提供内建的 SQLDB 组件,它提供 SQLite 数据库 ([[TSQLite3Connection]]) 从 [[Component Palette]] 的 [[SQLdb tab]],它允许你例如使用形如 [[Component Palette]] 的数据库组件来创建图形界面。使用 SQLDB 的有点是它可以很容易地更换到一个不同的数据库例如 FireBird 或 PostgreSQL,而不必太多修改你的程序。详情请见下文。
2020
2121#### Spatialite support
2222
2323Spatialite are GIS extensions to SQLite which you can use from within SQLDB. See [[Spatialite]].
2424
2525#### SQLite 加密的支持
2626
2727在近期的 FPC 版本 (从 FPC 3.0.0 开始, 在 2012年3月 实现), SQLDB 包括了对 SQLite3 的某些扩展版本的支持,这些版本使用 AES 算法加密 SQLite 数据库文件。 使用“Password”属性设置加密密钥。
2828
2929示例:
3030
3131- [SQLCipher](http://sqlcipher.net/): 开源, e.g. Windows 二进制文件不免费 (你必须自己编译它们)
3232- [System.Data.SQLite](http://system.data.sqlite.org/): 开源, Windows (32, 64, CE) 二进制文件可用, e.g 下载预编译的二进制文件之一并重命名SQLite.Interop.dll到sqlite3.dll(如果你正在使用静态链接的,想必你需要重命名System.Data.SQLite.DLL到sqlite3.dll)
3333- [wxSQLite3](http://wxcode.sourceforge.net/docs/wxsqlite3/): 开源, 一些 Linux 的二进制文件可用 (ex: <https://launchpad.net/ubuntu/oneiric/+package/libwxsqlite3-2.8-0>)
3434
3535根据您使用的内容,可能还需要在“5.0 C interface”处单独启用加密[如此处所写](https://www.sqlite.org/see/doc/trunk/www/readme.wiki), 在访问加密数据库之前,您需要使用产品密钥调用 sqlite3_activate_see() 。
3636
3737#### sqlite3backup
3838
3939sqlite3backup 是 FPC 提供的一个单元(不在 Lazarus 中,但可以通过编程方式使用),为 SQLite3 提供备份/恢复功能。 它使用 SQLDB 的 sqlite3conn。
4040
4141### Zeos
4242
4343[Zeos](https://sourceforge.net/projects/zeoslib/)
4444
4545### SQLitePass
4646
4747[SQLitePass](http://source.online.free.fr/) 组件. 2010年最后一次编码. 上次社区活跃在2011年.
4848
4949### TSQLite3Dataset 和 TSQLiteDataset
5050
5151还有单独的TSQLiteDataset(单元 sqlites)和TSQLite3Dataset(单元 sqlite3ds)包; 有关如何使用它们的说明,请参阅下文。 访问 [sqlite4fpc 主页](http://sqlite4fpc.yolasite.com/sqlite4fpc) 查找 API 参考和更多教程。
5252
5353TSqliteDataset 和 TSqlite3Dataset 是 [[TDataSet]] 后代,分别访问 2.8.x 和 3.x.x sqlite 数据库。 对于新项目,您可能会使用 TSQlite3Dataset,因为 SQLite 3.x 是当前版本。
5454
5555下面列出了与其他 FPC/Lazarus SQLite 驱动程序/访问方法相比的主要优点和缺点:
5656
5757优点:
5858
5959- 灵活:程序员可以选择使用或不使用 SQL 语言,允许他们使用简单的表布局或 SQL/sqlite 允许的任何复杂布局
6060
6161缺点:
6262
6363- 更改为其他数据库比使用 SQLDB 或 Zeos 组件更困难
6464
6565> **Note:** 鉴于上述情况,许多用户会因为 SQLDB 或 Zeos 的优点而使用 SQLDB 或 Zeos,除非他们需要对 SQLite 库进行较低级别的访问
6666
6767## 使用SQLdb组件以使用SQLite
6868
6969这些说明重点关注 SQLite 的 SQLDB (TSQLite3Connection) 细节。 有关一般概述,请查看 [[SqlDBHowto]],其中包含有关 SQLdb 组件的一些有用信息。
7070
7171有关创建为 SQLite/SQLDB(以及 Firebird/SQLDB、PostgreSQL/SQLDB,基本上任何 RDBMS SQLDB 支持)编写的支持 GUI 数据库的程序的教程,请参阅 [[SQLdb Tutorial1]]。
7272
7373我们将使用 Lazarus SQLdb 选项卡中的三个组件的组合:TSQLite3Connection、TSQLTransaction 和 TSQLQuery。 TSQLQuery 充当我们的 TDataset; 在最简单的情况下,它仅代表我们的一张表。 为了简单起见:确保您已经拥有一个现有的 SQLite 数据库文件,并且现在不需要创建新的文件。 如果您想自己声明或者在 FreePascal 中工作,TSQLite3Connection 可以在“sqlite3conn”单元中找到。
7474
7575这三个组件像平常一样相互连接:在 TSQLQuery 中设置属性 Database 和 Transaction,在 TSQLTransaction 中设置属性 Database。 Transaction 和 Connection 组件中没有太多可做的事情,大部分有趣的事情将在 TSQLQuery 中完成。 配置组件如下:
7676
7777TSQLite3Connection:
7878
7979- DatabaseName:将此属性设置为 SQLite 文件的文件名(绝对路径!)。 不幸的是,您不能简单地使用在设计时和运行时都保持不变的相对路径***这仍然是真的吗? 难道您不能在构建后的 shell 脚本中复制 db 文件或对其进行符号链接吗?***。 您应该确保在应用程序启动时始终以编程方式设置文件的正确路径,无论设计时包含什么内容。
8080
8181注意:要设置完整的库路径(如果您将 sqlite dll/so/dylib 放置在操作系统找不到它的地方,例如 Linux/OSX 上的应用程序目录),您可以设置 *SQLiteLibraryName* 属性(在建立任何连接之前,例如在主窗体的 OnCreate 事件中),如下所示:
8282
8383``` pascal
8484SQLiteLibraryName:='./sqlite3.so';
8585```
8686
8787TSQLQuery:
8888
8989- SQL:将其设置为对您的表之一进行一些简单的选择查询。 例如,如果您有一个表“foo”并希望此数据集代表该表,则只需使用以下内容:
9090 ``` SQL
9191 SELECT * FROM foo
9292 ```
9393
9494- Active:在 IDE 中将其设置为 True 以测试其是否全部设置正确。 这也将自动激活事务和连接对象。 如果收到错误,则连接的 DatabaseName 不正确或 SQL 查询错误。 稍后,当我们添加完字段(见下文)后,再次将它们全部设置为非活动状态,我们不希望 IDE 在测试应用程序时锁定 SQLite 数据库(单用户!)。
9595
9696- *可能不需要正确操作 - 需要检查(2012 年 6 月)* 现在我们可以将字段添加到 TSQLQuery 中。 当组件仍设置为活动状态时,右键单击并“编辑字段...”。 单击“+”按钮并添加字段。 它将列出您的 SQL 查询返回的所有字段。 添加您需要的每个字段,您还可以在此处添加查找字段; 在这种情况下,只需确保您已经在其他数据集中定义了所有需要的字段,然后再开始添加引用它们的查找字段。 如果您的表有很多列并且您不需要全部列,您可以将它们省略,您还可以使您的 SQL 更具体一些。
9797
9898- 在您的代码中,您需要调用 SQLQuery.ApplyUpdates 和 SQLTransaction.Commit,当与数据感知控件一起使用时,TSQLQuery.AfterPost 和 AfterInsert 事件是执行此操作的好地方,但当然您也可以将这些调用推迟到以后的时间。 如果您不调用它们,数据库将不会更新。
9999
100100- "Database is locked" :IDE 可能仍在锁定数据库(SQLite 是单用户数据库),您可能忘记在定义完 TSQLQuery 对象的所有字段后将组件设置为非活动状态并再次断开连接。 使用窗口的 OnCreate 事件设置路径并仅在运行时激活对象。 您在 IDE 中的 TSQLQuery 中设置的大多数内容不需要(有些甚至不允许)它们在设计时处于活动状态,唯一的例外是定义要读取表设计的字段, 所以设计时不活动应该是正常状态。
101101
102102- 您的表都应该有一个主键,并且您必须确保相应的字段具有 pfInKey 并且其 PoviderFlags 中没有其他内容(这些标志控制在自动构建更新和删除查询时如何以及在何处使用该字段)。
103103
104104- 如果您使用查找字段
105105 - 确保查找字段的 ProviderFlags 完全为空,这样它就不会尝试在更新查询中使用其名称。 查找字段本身不是数据字段,它只作用于另一个字段的值,即相应的关键字段,并且只有这个关键字段稍后才会在更新查询中使用。 您可以将关键字段设置为隐藏,因为通常您不希望在 DBGrid 中看到它,但需要定义它。
106106 - LookupCache 必须设置为 True。 在撰写本文时,由于某种原因,查找字段不会显示任何其他内容(但仍然有效),奇怪的是,使用 TSQLite3Dataset 或其他 TXXXDataset 组件时的情况恰恰相反,此处必须将其设置为 False。 我还不确定这是有意的行为还是错误。
107107
108108- 通常,对于简单的表,您不需要设置任何 InsertSQL、UpdateSQL 和 DeleteSQL 属性,只需将它们留空即可。 如果您正确设置了所有字段的 ProviderFlags,它应该能够动态创建所需的 SQL。 有关 InsertSQL、UpdateSQL 和 DeleteSQL 的更多详细信息,请参阅[[Working With TSQLQuery|Working_With_TSQLQuery#InsertSQL.2C_UpdateSQL_and_DeleteSQL_-_Basic_use_of_parameters]].
109109
110110正确设置上述所有内容后,您现在应该能够像任何其他 TDataset 一样使用 TSQLQuery,方法是通过以编程方式操作其数据,或者将 TDatasouce 放置在表单上,将其连接到 TSQLQuery,然后使用 TDBGrid 等数据控件。
111111
112112### 创建一个数据库
113113
114114从父类继承的[TSQLite3Connection.CreateDB](http://www.freepascal.org/docs-html/fcl/sqldb/tsqlconnection.createdb.html)方法实际上什么也不做; 要在尚不存在文件的情况下创建数据库,您只需编写表数据,如下例所示:
115115
116116(从 Lazarus 1.3 及以上版本附带的 sqlite_encryption_pragma 示例中提取的代码)
117117
118118``` pascal
119119var
120120 newFile : Boolean;
121121begin
122122
123123 SQLite3Connection1.Close; // 确保启动时连接已关闭
124124
125125 try
126126 // 由于我们是第一次创建这个数据库,
127127 // 检查文件是否已经存在
128128 newFile := not FileExists(SQLite3Connection1.DatabaseName);
129129
130130 if newFile then
131131 begin
132132 // 创建数据库和表
133133 try
134134 SQLite3Connection1.Open;
135135 SQLTransaction1.Active := true;
136136
137137 // 这里我们在新数据库中设置一个名为“DATA”的表
138138 SQLite3Connection1.ExecuteDirect('CREATE TABLE "DATA"('+
139139 ' "id" Integer NOT NULL PRIMARY KEY AUTOINCREMENT,'+
140140 ' "Current_Time" DateTime NOT NULL,'+
141141 ' "User_Name" Char(128) NOT NULL,'+
142142 ' "Info" Char(128) NOT NULL);');
143143
144144 // 根据DATA表中的id创建索引
145145 SQLite3Connection1.ExecuteDirect('CREATE UNIQUE INDEX "Data_id_idx" ON "DATA"( "id" );');
146146
147147 SQLTransaction1.Commit;
148148
149149 ShowMessage('Succesfully created database.');
150150 except
151151 ShowMessage('Unable to Create new Database');
152152 end;
153153 end;
154154 except
155155 ShowMessage('Unable to check if database file exists');
156156 end;
157157 end;
158158```
159159
160160### 创建用户定义的排序规则
161161
162162``` pascal
163163// utf8 区分大小写的比较回调函数
164164function UTF8xCompare(user: pointer; len1: longint; data1: pointer; len2: longint; data2: pointer): longint; cdecl;
165165var S1, S2: AnsiString;
166166begin
167167 SetString(S1, data1, len1);
168168 SetString(S2, data2, len2);
169169 Result := UnicodeCompareStr(UTF8Decode(S1), UTF8Decode(S2));
170170end;
171171
172172// utf8 不区分大小写的比较回调函数
173173function UTF8xCompare_CI(user: pointer; len1: longint; data1: pointer; len2: longint; data2: pointer): longint; cdecl;
174174var S1, S2: AnsiString;
175175begin
176176 SetString(S1, data1, len1);
177177 SetString(S2, data2, len2);
178178 Result := UnicodeCompareText(UTF8Decode(S1), UTF8Decode(S2));
179179end;
180180
181181// 使用 SQLite3 API 注册排序规则(需要 sqlite3dyn 单元):
182182sqlite3_create_collation(SQLite3.Handle, 'UTF8_CI', SQLITE_UTF8, nil, @UTF8xCompare_CI);
183183// 或使用 TSQLite3Connection 的方法:
184184CreateCollation('UTF8_CI',1,nil,@UTF8xCompare_CI);
185185
186186// 现在我们可以在 SQL 中使用不区分大小写的比较,例如:
187187// SELECT * FORM table1 WHERE column1 COLLATE UTF8_CI = 'á'
188188
189189// 但这对于 LIKE 运算符不起作用
190190// 为了也支持 LIKE 运算符,我们必须使用 sqlite3_create_function() 重载默认的 LIKE 函数
191191// http://www.sqlite.org/lang_corefunc.html#like
192192```
193193
194194### 创建用户定义的函数
195195
196196``` pascal
197197// 使用用户提供的函数重载默认 LOWER() 函数的示例
198198// 要运行此演示,您必须将单元'sqlite3dyn'和'ctypes'添加到您的uses-clause中
199199// 并添加一个值为 $800 的 const 'SQLITE_DETERMINISTIC'
200200
201201procedure UTF8xLower(ctx: psqlite3_context; N: cint; V: ppsqlite3_value); cdecl;
202202var S: AnsiString;
203203begin
204204 SetString(S, sqlite3_value_text(V[0]), sqlite3_value_bytes(V[0]));
205205 S := UTF8Encode(AnsiLowerCase(UTF8Decode(S)));
206206 sqlite3_result_text(ctx, PAnsiChar(S), Length(S), sqlite3_destructor_type(SQLITE_TRANSIENT));
207207end;
208208
209209// 注册函数 LOWER() 使用 SQLite3 API (requires sqlite3dyn unit):
210210sqlite3_create_function(SQLite3.Handle, 'lower', 1, SQLITE_UTF8 or SQLITE_DETERMINISTIC, nil, @UTF8xLower, nil, nil);
211211```
212212
213213### SQLite3 与日期
214214
215215- SQLite 3 不将日期存储为特殊的 DateTime 值。 它可以将它们存储为字符串、双精度数或整数 - 请参阅
216216
217217<http://www.sqlite.org/datatype3.html#datetime>。
218218
219219- 在字符串中,根据 SQL 标准/ISO 8601,日期分隔符为“-”。因此,如果您使用内置 DATE 函数执行 INSERT,它会将其存储为“YYYY-MM-DD”之类的内容。
220220- 如果数据集存储为字符串,则读取 DateTime 值可能会导致数据集出现问题:.AsDateTime 限定符可能会在 SQLite“字符串日期”上停止,但这可以通过使用类似 `strftime(`*`%d/% m/%Y`*`,recdate) AS sqlite3recdate` 在 SQL SELECT 语句中,强制 SQLite3 以指定格式返回日期记录。 (格式字符串 %d/%m/%d 对应于 .AsDateTime 能够理解的区域设置日期格式) **==\> 请打开错误报告,其中包含演示问题的示例应用程序(如果是这种情况)**
221-- 当比较存储为字符串的日期时(例如使用 BETWEEN 函数),请记住比较将始终是<b>字符串</b>比较,因此取决于您存储日期值的方式。
221+- 当比较存储为字符串的日期时(例如使用 BETWEEN 函数),请记住比较将始终是字符串比较,因此取决于您存储日期值的方式。
222222
223223#### 默认值采用当地时间而不是 UTC
224224
225225CURRENT_TIME、CURRENT_DATE 和 CURRENT_TIMESTAMP 返回当前 UTC 日期和/或时间。 对于本地日期和/或时间,我们可以使用:
226226
227227`  DEFAULT (datetime('now','localtime')) 对于格式为 YYYY-MM-DD HH:MM:SS 的日期时间值`\
228228`  DEFAULT (date('now','localtime')) 对于格式为 YYYY-MM-DD 的日期值`\
229229`  DEFAULT (time('now','localtime')) 格式为 HH:MM:SS 的时间值`
230230
231231### SQLDB 和 SQLite 故障排除
232232
233233- 请记住,为了使设计时支持(字段等)发挥作用,Lazarus 也必须找到 sqlite3.dll。
234234- 数据库文件名也是如此。 如果您使用组件来提取,请始终使用绝对路径,例如 设计时的字段名称。 否则 IDE 将在其目录中创建一个空文件。 如果出现问题,请检查 lazarus/ 目录是否不包含数据库文件的零字节副本。
235235- 如果您有主/从关系,则需要在每次插入后刷新主数据集,以便获取从数据集外键字段的值。 您可以在主数据集的 AfterPost 事件中通过调用以下重载过程之一来执行此操作:
236236
237237``` pascal
238238interface
239239 procedure RefreshADatasetAfterInsert(pDataSet: TSQLQuery);overload;
240240 procedure RefreshADatasetAfterInsert(pDataSet: TSQLQuery; pKeyField: string);overload;
241241
242242implementation
243243
244244procedure RefreshADatasetAfterInsert(pDataSet: TSQLQuery; pKeyField: string);
245245//此过程刷新数据集并将光标定位到最后一条记录
246246//如果数据集不能保证按自动增量主键排序,则使用
247247var
248248 vLastID: Integer;
249249 vUpdateStatus : TUpdateStatus;
250250begin
251251 vUpdateStatus := pDataset.UpdateStatus;
252252 //获取数据库中最后插入的ID
253253 pDataset.ApplyUpdates;
254254 vLastID:=(pDataSet.DataBase as TSQLite3Connection).GetInsertID;
255255 //Now come back to respective row
256256 if vUpdateStatus = usInserted then begin
257257 pDataset.Refresh;
258258 //刷新并返回相应行
259259 pDataset.Locate(pKeyField,vLastID,[]);
260260 end;
261261end;
262262
263263procedure RefreshADatasetAfterInsert(pDataSet: TSQLQuery);
264264//此过程刷新数据集并将光标定位到最后一条记录
265265//仅在保证DataSet按自动增量主键排序时使用
266266var
267267 vLastID: Integer;
268268 vUpdateStatus : TUpdateStatus;
269269begin
270270 vUpdateStatus := pDataset.UpdateStatus;
271271 pDataset.ApplyUpdates;
272272 vLastID:=(pDataSet.DataBase as TSQLite3Connection).GetInsertID;
273273 if vUpdateStatus = usInserted then begin
274274 pDataset.Refresh;
275275 //危
276276 pDataSet.Last;
277277 end;
278278end;
279279
280280procedure TDataModule1.SQLQuery1AfterPost(DataSet: TDataSet);
281281begin
282282 RefreshADatasetAfterInsert(Dataset as TSQLQuery); //如果你的数据集是按主键排序的
283283end;
284284
285285procedure TDataModule1.SQLQuery2AfterPost(DataSet: TDataSet);
286286begin
287287 RefreshADatasetAfterInsert(Dataset as TSQLQuery, 'ID'); //如果你不确定数据集总是按主键排序
288288end;
289289```
290290
291291### 真空和其他必须在事务外完成的操作
292292
293293SQLDB 似乎总是需要connection,但某些操作(例如 Pragma 和 Vacuum)必须在transaction之外完成。 诀窍是结束transaction,执行你必须做的事情然后在此开始transaction(这样sqldb就不会混淆:)
294294
295295``` pascal
296296 // 提交任何挂起的操作或使用“新”sql连接
297297 Conn.ExecuteDirect('End Transaction'); // 结束由 SQLdb 启动的transaction
298298 Conn.ExecuteDirect('Vacuum');
299299 Conn.ExecuteDirect('Begin Transaction'); // 启动一个transaction供 SQLdb 使用
300300```
301301
302302## 使用 TSQLite3Dataset
303303
304304本节详细介绍如何使用 TSQLite2Dataset 和 TSQLite3Dataset 组件访问 SQlite 数据库。 by Luiz Américo luizmed(at)oi(dot)com(dot)br
305305
306306#### 要求
307307
308308- 对于 sqlite2 数据库 (遗留):
309309 - FPC 2.0.0 或更高
310310 - Lazarus 0.9.10 或更高
311311 - SQLite 运行库 2.8.15 或更高*
312312
313313- Sqlite2 不再被维护,二进制文件在sqlite网站找不到
314314
315315- 对于 sqlite3 数据库:
316316 - FPC 2.0.2 或更高
317317 - Lazarus 0.9.11 (svn revision 8443) 或更高
318318 - sqlite 运行库 3.2.1 或更高 (从这里获取: [www.sqlite.org](http://www.sqlite.org))
319319
320320**在初始化一个Lazarus项目之前, 确保:**
321321
322322- sqlite库是
323323 - 在系统的PATH 或
324324 - 在可执行输出目录和Lazarus(或当前项目)目录 - 这个选项可能只在Windows上有效
325325- 在Linux下, 将cmem作为主程序uses子句中的第一个单元
326326 - 在 Debian、Ubuntu 和其他类似 Debian 的发行版中,为了构建 Lazarus IDE,您必须安装软件包 libsqlite-dev/libsqlite3-dev,而不仅仅是 sqlite/sqlite3(也适用于 OpenSuSe)
327327
328328#### 怎样使用 (基础用法)
329329
330330安装在 /components/sqlite 目录中找到的包 (见说明: [[Install Packages|here]])
331331
332332在设计时,设置以下属性:
333333
334334- FileName: sqlite 文件的路径 \[必填\]
335335- TableName: sql语句中使用的表名\[必填\]
336336- SQL:一条SQL select语句\[可选\]
337337- SaveOnClose:默认值为 false,表示不保存更改。 可以将其更改为 true。\[可选\]
338338- Active:需要在设计时或程序启动时设置。 \[必填\]
339339
340340**创建表 (Dataset)**
341341
342342双击组件图标或使用单击鼠标右键时出现的弹出菜单中的“创建表”项。 将显示一个简单的不言自明的表格编辑器。
343343
344344以下是 TSqliteDataset 和 TSqlite3Dataset 支持的所有字段类型:
345345
346346- Integer
347347- AutoInc
348348- String
349349- Memo
350350- Bool
351351- Float
352352- Word
353353- DateTime
354354- Date
355355- Time
356356- LargeInt
357357- Currency
358358
359359**检索数据**
360360
361361创建表后或使用之前创建的表,使用 Open 方法打开数据集。 如果未设置 SQL 属性,则将检索所有字段中的所有记录,如果将 SQL 设置为:
362362
363363``` pascal
364364SQL := 'Select * from TABLENAME';
365365```
366366
367367**将更改应用到基础数据文件**
368368
369369要使用ApplyUpdates函数,数据集必须至少包含一个满足主键要求的字段(值必须是UNIQUE且不为NULL)
370370
371371可以通过两种方式做到这一点:
372372
373373- 将 PrimaryKey 属性设置为主键字段的名称
374374- 添加一个 AutoInc 字段(这更容易,因为 TSqliteDataSet 自动将其作为主键处理)
375375
376376如果设置了两个条件之一,则只需调用
377377
378378``` pascal
379379ApplyUpdates;
380380```
381381
382382> **Note:** 如果两个条件都设置了,则使用 PrimaryKey 对应的字段来应用更新。
383383
384384> **Note:** 将PrimaryKey设置为非主键的字段,如果调用ApplyUpdates,将导致数据丢失,因此在使用之前请确保所选字段不包含Null和Unique值。
385385
386386##### 大纲/详细信息示例
387387
388388主/详细关系的各种示例(例如客户和订单之间的关系):
389389
390390- 使用 `DataSource` 属性执行此操作的通用 SQLDB 方法:[[MasterDetail]]
391391- 使用locate 的TSQLite3 特定示例:[[TSqlite3 TSqlite3 Master Detail Example]]。
392392
393393#### 评论
394394
395395- 尽管已经用 10,000 条记录进行了测试并且工作正常,但 TSqliteDataset 将所有数据保留在内存中,因此请记住仅检索必要的数据(尤其是备注字段)。
396396- 同一数据文件(Filename 属性)可以托管多个表/数据集
397397- 可以使用同一个表同时创建多个数据集(不同的字段组合)
398398- 可以使用sql中的WHERE语句过滤数据,关闭并重新打开数据集(或调用RefetchData方法)。 但在这种情况下,字段的顺序和数量必须保持不变
399399- 也可以使用复杂的 SQL 语句,在多个表中使用别名、联接、视图(记住它们必须驻留在同一个数据文件中),但在这种情况下,ApplyUpdates 将不起作用。 如果有人想要使用复杂的查询并将更新应用到数据文件,请发邮件给我,我将给出一些如何做到这一点的提示
400400- 允许将文件名设置为不是由 TSqliteDataset 创建的 sqlite 数据文件并打开它,但某些字段不会检测到正确的字段类型。 这些将被视为字符串字段。
401401
402402通用示例可以在 fpc/fcl-db/src/sqlite SVN 目录中找到
403403
404404## 也可以看看
405405
406406- [[SQLdb Tutorial1]] Tutorial for Sqlite
407407- [[SqlDBHowto]] General information on SQLDB
408408- [[Working With TSQLQuery]] Information on SQLDB's TSQLQuery
409409- [SQLite site](http://www.sqlite.org)
410410
411411---
412412*From the Free Pascal wiki, page "SQLite/zh CN", as it stood on 2023-07-15 after a change by Iruanp, 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