Sign in Join
Wiki copytemporary

Lazarus Tdbf Tutorial/zh CN: what changed

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

OldNewLine
11## 概览
22
33该教程是关于基础的数据库开发,使用Lazarus的 [TDbf](https://tdbf.sf.net) 组件 (by Micha Nelissen)。 针对TDbf 还有额外的文档可用。本页英文由Tony Maro创建,欢迎大家修订!
44
55需要 TDbf 的pdf文档可以去这个[SourceForge](https://sourceforge.net/project/showfiles.php?group_id=34085&package_id=26371) 网站。It may be useful to keep that pdf alongside this document while reading.
66
77### 你需要什么
88
99TDbf 组件已经在 Lazarus 0.913版本后默认安装(Data Access标签)。
1010
1111No doubt this will soon be easier as FreePascal releases the next version 2.0, however currently you will need a recent CVS edition of FPC 1.9.X in order to properly use the TDbf component. It may be possible to download just the TDbf component by itself and use it with the 1.1 version of FreePascal, however this document was written with 1.9.X in mind, partly due to bug fixes in the other database components used in Lazarus.
1212
1313### TDbf 组件能提供什么
1414
1515TDbf 为Lazarus(等)提供访问 dBase 或 FoxPro 数据表。它允许读、写和创建 dBase III+, dBase IV, Visual dBase VII and FoxPro 版本的数据库文件。它工作并不需要额外库文件或者数据引擎。 你要做只是简单地拖动 TDbf 组件到你的表单,你就立刻拥有操作一个跨平台数据库的环境。TDbf 通过Lazarus能够工作在 Windows 和 Linux。
1616
1717## 如何创建一个新的数据表
1818
1919Lazarus没有提供 "Database Desktop" 这样的桌面数据库应用程序, 我们将在程序中建一个新的Dbase表.
2020
2121### 设置数据文件路径
2222
2323It's a good idea to give your application's database it's own directory. This simplifies making backups of the data. There are two ways to set the path. You can set the full path using the FilePathFull property, or you can set a path relative to the current application path with FilePath. For instance, setting "FilePath" at runtime to "data/" would use a data subdirectory just below the executable file. Setting the "FilePathFull" property to "/var/data/" would place everthing in that exact folder, ignoring the application's location.
2424
2525### 选择数据库版本
2626
2727缺省情况下, TDbf 会自动创建 dBase IV 格式的dbf数据库文件. 虽然这种格式的数据库兼容很强, 但有些功能可能不被支持. 如果你需要auto-incrementing fields自动递增字段, 你就必须使用更高级别的.
2828
29-`TDbf 支持的数据库格式:`
29+```text
30+TDbf 支持的数据库格式:
31+```
3032
3133- 3 dBase III+
3234- 4 dBase IV
3335- 7 Visual dBase VII
3436- 25 FoxPro
3537
3638你选择一个正确的数据库格式,应用适当属性.
3739
3840### 添加字段
3941
4042Creating fields for your new table at runtime pretty much follows the old Delphi standard. Once you have set your FilePath, TableLevel, and TableName properties, manipulate the FieldDefs property to set up the structure. For example:
4143
42-`MyDbf.FilePathFull := '/location/to/my/data';`\
43-`MyDbf.TableLevel := 7;`\
44-`MyDbf.TableName := 'customers.dbf'; // note: is the .dbf really required?`\
45-`With MyDbf.FieldDefs do begin`\
46-`  Add('Id', ftAutoInc, 0, True);`\
47-`  Add('Name', ftString, 80, True);`\
48-`End;`
44+``` pascal
45+MyDbf.FilePathFull := '/location/to/my/data';
46+MyDbf.TableLevel := 7;
47+MyDbf.TableName := 'customers.dbf'; // note: is the .dbf really required?
48+With MyDbf.FieldDefs do begin
49+ Add('Id', ftAutoInc, 0, True);
50+ Add('Name', ftString, 80, True);
51+End;
52+```
4953
5054Field types are defined as:
5155
5256- ftUnknown
5357- **ftString**
5458- **ftSmallInt**
5559- **ftInteger**
5660- **ftWord**
5761- **ftBoolean**
5862- **ftFloat**
5963- **ftCurrency** (TableLevel 25)
6064- **ftBCD** (TableLevel 25)
6165- **ftDate**
6266- ftTime
6367- **ftDateTime**
6468- **ftBytes** (TableLevel 25)
6569- ftVarBytes
6670- **ftAutoInc** (TableLevel 7 or 25)
6771- **ftBlob**
6872- **ftMemo**
6973- ftGraphic
7074- ftFmtMemo
7175- ftParadoxOle
7276- **ftDBaseOle**
7377- ftTypedBinary
7478- ftCursor
7579- **ftFixedChar**
7680- **ftWideString**
7781- **ftLargeInt**
7882- ftADT
7983- ftArray
8084- ftReference
8185- ftDataSet
8286- ftOraBlob
8387- ftOraClob
8488- ftVariant
8589- ftInterface
8690- ftIDispatch
8791- ftGuid
8892- ftTimeStamp
8993- ftFMTBcd
9094
9195Bold types are currently supported
9296
9397### Go ahead and create it!
9498
9599Once you have defined the fields you wish to use in your new table, you can go ahead and create it with:
96100
97-`   MyDbf.CreateTable;`
101+```text
102+ MyDbf.CreateTable;
103+```
98104
99105## 如何向表增加索引
100106
101107如果你的数据库有大量数据记录,那么你就需要建索引文件来加快搜索的速度。定义表的索引字段,在创建数据库索引文件时,数据库被独占锁定。
102108
103-`       MyDbf.Exclusive := True;`\
104-`       MyDbf.Open;`
109+``` pascal
110+ MyDbf.Exclusive := True;
111+ MyDbf.Open;
112+```
105113
106114现在,我们要为数据库添加索引
107115
108-`       MyDbf.AddIndex('custid', 'Id', [ixPrimary, ixUnique]);`\
109-`       MyDbf.AddIndex('custname','Name', [ixCaseInsensitive]);`\
110-`       MyDbf.Close;`
116+```text
117+ MyDbf.AddIndex('custid', 'Id', [ixPrimary, ixUnique]);
118+ MyDbf.AddIndex('custname','Name', [ixCaseInsensitive]);
119+ MyDbf.Close;
120+```
111121
112122## Put it all together and you get...
113123
114124The following sample creates a new table "customers" in code. This of course only needs done once, and after that you just OPEN the table, don't create it ;-)
115125
116-`{$MODE OBJFPC}`\
117-`Program DatabaseTest;  `\
118-`{ We will require the following units be in the USES clause: }`\
119-` uses Dbf, db, Dbf_Common;                                   `\
120-`{ The Dbf is put there when you drop the TDbf on a form...   }`\
121-`{ but you will need db for the DataSet object and Dbf_Common }`\
122-`{ for things such as the field type definitions              }`\
123-`var`\
124-`  MyDbf: TDbf;`\
125-`begin`\
126-`  MyDbf := TDbf.Create(nil);`\
127-`  try`\
128-`    { use relative path to "data" directory }`\
129-`    MyDbf.FilePath := 'data/'; `\
130-`    { we want to use Visual dBase VII compatible tables }`\
131-`    MyDbf.TableLevel := 7;`\
132-`    MyDbf.Exclusive := True;`\
133-`    MyDbf.TableName := 'customers.dbf';`\
134-`    With MyDbf.FieldDefs do begin`\
135-`      Add('Id', ftAutoInc, 0, True);`\
136-`      Add('Name', ftString, 80, True);`\
137-`    End;`\
138-`    MyDbf.CreateTable;`\
139-`    MyDbf.Open;`\
140-`    MyDbf.AddIndex('custid', 'Id', [ixPrimary, ixUnique]);`\
141-`    { add a secondary index }`\
142-`    MyDbf.AddIndex('custname','Name', [ixCaseInsensitive]);`\
143-`    MyDbf.Close;`\
144-`  finally`\
145-`    MyDbf.Free;`\
146-`  end;`\
147-`end;`
126+``` pascal
127+{$MODE OBJFPC}
128+Program DatabaseTest;
129+{ We will require the following units be in the USES clause: }
130+ uses Dbf, db, Dbf_Common;
131+{ The Dbf is put there when you drop the TDbf on a form... }
132+{ but you will need db for the DataSet object and Dbf_Common }
133+{ for things such as the field type definitions }
134+var
135+ MyDbf: TDbf;
136+begin
137+ MyDbf := TDbf.Create(nil);
138+ try
139+ { use relative path to "data" directory }
140+ MyDbf.FilePath := 'data/';
141+ { we want to use Visual dBase VII compatible tables }
142+ MyDbf.TableLevel := 7;
143+ MyDbf.Exclusive := True;
144+ MyDbf.TableName := 'customers.dbf';
145+ With MyDbf.FieldDefs do begin
146+ Add('Id', ftAutoInc, 0, True);
147+ Add('Name', ftString, 80, True);
148+ End;
149+ MyDbf.CreateTable;
150+ MyDbf.Open;
151+ MyDbf.AddIndex('custid', 'Id', [ixPrimary, ixUnique]);
152+ { add a secondary index }
153+ MyDbf.AddIndex('custname','Name', [ixCaseInsensitive]);
154+ MyDbf.Close;
155+ finally
156+ MyDbf.Free;
157+ end;
158+end;
159+```
148160
149161## 外部索引文件
150162
151163The TDbf also supports storing secondary indexes in a separate file. This might be helpful if the database is expected to be very large. Secondary index files are created almost identically to normal indexes, but with the addition of the '.ndx' file extension:
152164
153-`    MyDbf.AddIndex('custname.ndx','Name', [ixCaseInsensitive]);`
165+```text
166+ MyDbf.AddIndex('custname.ndx','Name', [ixCaseInsensitive]);
167+```
154168
155169Each time the TDbf is opened, the index file must be loaded:
156170
157-`    MyDbf.OpenIndexFile('custname.ndx');`
171+```text
172+ MyDbf.OpenIndexFile('custname.ndx');
173+```
158174
159175And indexes must be referenced including the extension:
160176
161-`    MyDbf.IndexName := 'custname.ndx';`
177+``` pascal
178+ MyDbf.IndexName := 'custname.ndx';
179+```
162180
163181Index files are packed separately using:
164182
165-`    MyDbf.CompactIndexFile('custname.ndx');`
183+```text
184+ MyDbf.CompactIndexFile('custname.ndx');
185+```
166186
167187## 如何连接 TDbf 组件到 数据感知组件
168188
169189上面的例子显示了如何创建一个新的数据表,通过代码方式。使用这个表更为简单。
170190
171191Lazarus的数据感知组件(data-aware,象TDbEdit,在Data Controls面板)连接到一个 TDataSource 组件,使用它们的"DataSource" 和 "DataField" 属性。TDataSource 组件会处理数据库引擎 和 数据感知组件 这二者之间的通信。一个 TDataSource then 连接到 the TDbf component 使用它的 "DataSet" 属性。这种(组件之间的)连接看起来象这样:
172192
173-`TDbEdit-------`\
174-`             |`\
175-`TDbEdit------|-->TDataSource-->TDbf`\
176-`             |`\
177-`TDbNavigator--`
193+```text
194+TDbEdit-------
195+ |
196+TDbEdit------|-->TDataSource-->TDbf
197+ |
198+TDbNavigator--
199+```
178200
179201请确认 FilePath (或 FilePathFulll), TableLevel, 和 TableName 等属性,在你的 TDbf 组件,然后调用(before calling):
180202
181-`TDbf.Active := True;`
203+``` pascal
204+TDbf.Active := True;
205+```
182206
183207还有很多可以说的,关于Lazazrus中的数据库编程,并且我建议,一本好的 Delphi 数据库编程书籍 或 two as the underlying concepts are the same. I constantly refer to my copy of "Delphi 2 Unleashed" because the concepts and basic code haven't changed much in 8 years.
184208
185209## 压缩和重建 DBF 数据库表
186210
187211因为 DBF 文件结构特性,在使用数据删除操作时,并没有真正的从物理表中删除数据,只是会给这条数据打上一个删除标记。这时你必须对数据库表进行“pack”操作,回收占用的空间。这应以独占模式设置。
188212
189-`MyDbf.Exclusive := True;`\
190-`MyDbf.Open;`\
191-`MyDbf.PackTable;`\
192-`// 同时重建数据库索引文件`\
193-`MyDbf.RegenerateIndexes;`\
194-`MyDbf.Close;`\
195-`MyDbf.Exclusive := False;`
213+``` pascal
214+MyDbf.Exclusive := True;
215+MyDbf.Open;
216+MyDbf.PackTable;
217+// 同时重建数据库索引文件
218+MyDbf.RegenerateIndexes;
219+MyDbf.Close;
220+MyDbf.Exclusive := False;
221+```
196222
197223## Master table relations
198224
199225Real power in database programming begins when you have multiple tables that reference each other. While TDbf does not yet support referential integrity, it does support a master / detail relationship between TDbf's.
200226
201227When there are two tables related, for instance:
202228
203-`[customers]`\
204-`Id       <----|`\
205-`Name          |`\
206-`Phone         |`\
207-`Address       |`\
208-`              |  The CustID in invoices references a customer primary  field`\
209-`[invoices]    |`\
210-`Id            |`\
211-`Amount        |`\
212-`CustID   -----|  * This field indexed as "idxcustid"`
229+```text
230+[customers]
231+Id <----|
232+Name |
233+Phone |
234+Address |
235+ | The CustID in invoices references a customer primary field
236+[invoices] |
237+Id |
238+Amount |
239+CustID -----| * This field indexed as "idxcustid"
240+```
213241
214242If you wanted to display all invoices for a given customer, the detail table (invoices) can stay in sync with the master table (customers) automatically.
215243
216244On the invoices TDbf component set the following:
217245
218-`InvDbf.IndexName := 'idxcustid'; // our field that will match the customers table ID`\
219-`InvDbf.MasterSource := dsCustomers; // datasource that is linked to the customers TDbf`\
220-`InvDbf.MasterFields := 'Id'; // field on the customers table we are matching against our index`
246+``` pascal
247+InvDbf.IndexName := 'idxcustid'; // our field that will match the customers table ID
248+InvDbf.MasterSource := dsCustomers; // datasource that is linked to the customers TDbf
249+InvDbf.MasterFields := 'Id'; // field on the customers table we are matching against our index
250+```
221251
222252## 示例应用 - DB Browser
223253
224254I've written a simple application that will use the TDbf to open and display database tables using the dbGrid control. The Linux executable along with project sources which should compile fine in Windows is available from: [tony.maro.net](http://tony.maro.net/mod.php?mod=downloads&op=showcat&id=3&level=1)
225255
226256## 你需要关心的其他事情
227257
228258Currently there is no support for referential integrity, or internally encrypted .dbf files.
229259
230260## See also
231261
232262- [[Example: TDbf (creating table and indexes, selecting of index)]]
233263
234264---
235265*From the Free Pascal wiki, page "Lazarus Tdbf Tutorial/zh CN", as it stood on 2016-01-23 after a change by FTurtle, 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).*
236266Category: zh

Back to history