Delphi中ClientDataSet的用法小结

TClientDataSet控件继承自TDataSet,其数据存储文件格式扩展名为 .cds,是基于文件型数据存储和操作的控件。该控件封装了对数据进行操作处理的接口和功能,而本身并不依赖上述几种数据库驱动程序,基本上能满足单机"瘦"数据库应用程序的需要。

一、TClientDataSet的基本属性和方法介绍

1、FieldDefs: 字段定义列表属性

开发者可通过单击属性编辑器中该属性编辑按钮,或在该控件上单击右键选择弹出菜单中的"Fields Editor"菜单进行字段编辑。设置完此属性后,实际上就相当于定义了表的结构;如果想装入已有的数据表的结构和数据,可通过单击右键选择弹出菜单中的"Assign Local Data"菜单,从弹出对话框中选取当前窗体中已与数据库连接好的数据集控件名称即可(当前窗体中必须已放置好要套用的数据集控件并打开激活)。

使用注意:

  对于自定义的字段名表,该属性编辑完后,该控件仍然无法打开。必须右键单击该控件,选择弹出菜单中的"Create DataSet"菜单,让该控件以上述编辑的字段列表为依据,创建数据集后,才能够被激活打开和使用。否则,会出现类似"ClientDataSet1: Missing data provider or data packet."的错误(包括在运行期,运行期可调用该控件的CreateDataSet方法,从而动态定义字段和表)。

2、FileName属性

说明:数据存储文件的名称。因该控件是基于文件型的数据操作控件,因此,必须指定所操作的数据文件名称(默认扩展名称.cds),从而打开和激活该控件,进而进行数据编辑。

例1:利用此属性打开指定的.cds文件

var  
  Path: string;  
begin  
 Path := ExtractFilePath(Application.ExeName); //取得可执行文件路径  
 CDataSet1.FileName := Path + 'test.cds';  
 CDataSet1.Open;  
end;  

3、CreateDataSet方法

说明:该方法以FieldDefs中的字段名表为结构建立数据集,常用来进行动态定义表。

例2:动态创建一具有姓名和年龄两个字段的数据集。

//创建字段名表  
CDataSet.FieldDefs.Clear;  
with CDataSet.FieldDefs.AddFieldDef do  
begin  
 Name := 'Name';  
 Size := 10;  
 DataType := ftString;  
end;  
with CDataSet.FieldDefs.AddFieldDef do  
begin  
 Name := 'Age';  
 DataType := ftInteger;  
end;  
  
//动态创建数据集  
 CDataSet.CreateDataSet;  
//激活和打开该数据集  
 CDataSet.Open;  

4、Open方法

说明: 打开和激活数据集控件,从而进行数据编辑。a. 如果指定了FileName属性,则直接用Open方法即可打开和激活该控件,见例1。b. 如果未指定FileName属性,可使用例2方法动态创建和打开数据集,进而操作数据。

5、LoadFromFile和SaveToFile

说明:从文件中装入表结构和数据以及存储数据到文件。该方法类似于Word中的打开新文件和另存为的功能。

例3:将数据集的数据存储到指定文件中

CDataSet.SaveToFile('C:\Windows\ZHU\Test.cds');  

6、First(到首),Prior(向前),Next(向后),Last(到尾),Edit(编辑),CanCel(取消编辑),Post(保存),Insert(插入记录),Append(添加记录),Delete(删除),Refresh(数据刷新)等数据集常用方法。

说明:当指定了FileName属性时,其Post方法可将数据存入指定的文件中,类似其SaveToFile方法;如果未指定存储文件名,则Post方法只将数据存储在RAM中。其它方法,同一般数据集控件使用方法,略。

7、Filter, Filtered: 过滤筛选属性

说明:用于筛选指定条件的记录,用法同一般数据集控件,略。

例4:在已经激活打开的数据集中筛选性别为男性的记录

CDataSet.Close;  
CDataSet.Filter := '性别=''' + '男' + '''';  
CDataSet.Filtered := True;  
CDataSet.Open;  

二、使用TClientDataSet控件的应用程序发布的注意事项:

如前所述,使用TClientDataSet控件的程序发布时不需要任何数据库驱动程序,大大节省了安装文件的大小。但是,在发布程序时别忘了将Windows系统目录下midas.dll(257KB)与应用程序一起发布(运行必须),否则,程序仍然无法正常运行。

通过使用Delphi中TClientDataSet控件,既实现了应用程序可彻底脱离数据库驱动程序,也实现了常规数据集控件简单易用的特性,为编写"瘦"数据库应用程序提供了一种技术方法和手段。

三、TClientDataSet在三层结构中,TClientDataSet的地位是不可估量的,本文从以下几个方面阐述她的使用。

1、动态索引

procedure TForm1.DBGrid1TitleClick(Column: TColumn);  
begin  
   if (not column.Field is Tblobfield) then//Tblobfield不能索引,二进制  
  ClientDataSet1.IndexFieldNames:=column.Field.FieldName;  
end;  

2、多层结构中主从表的实现

设主表ClientDataSet1.packetrecord为-1,所有记录;

设从表ClientDataSet1.packetrecord为0,当前记录。

3、Taggregates使用

(1)在字段编辑中add new field类型为aggregates

后设置expression(表达试)

设置active:=true即可

使用dbedit的field为前者即可

(2)使用Aggergates属性add设计表达试

调用

ShowMessage(FloatTostr(ClientDataSet1.Aggregates.Count));  
ShowMessage(ClientDataSet1.Aggregates.Items[0].Value);  

4、在单层数据库中不要BDE

使用ClientDataSet代替table,使用ClientDataSet的loadfilename装入cds代替table的tablename的db或者dbf

引用:

原来的程序改造方法:

加一个ClientDataSet,使用右键assign locate data

后savetofile,再loadfromfile,后删除table

将原连table的datasource设为ClientDataSet

唯一注意的是:要将midas.dll拷到system或者当前目录

5、三层结构的公文包的实现方法

同时设定:filename(*.cds)2.remote server

6、可以对data赋值(从另一个数据集取值)

ClientDataSet2.Data:=ClientDataSet1.Data;  
ClientDataSet2.Open;  

或者

ClientDataSet2.CloneCursor(ClientDataSet1,true);  
ClientDataSet2.Open;  

7、附加数据取得

客户程序向应用服务器请求数据。如果TClientDataSet 的FetchOnDemand 属性设为True,客户程序会根据需要自动检索附加的数据包如BLOB字段的值或嵌套表的内容。否则,客户程序需要显式地调用GetNextPacket 才能获得这些附加的数据包。ClientDataSet的packetrecords设置一次取得的记录个数。

8、ClientDataSet与服务器端query连接方法

(1)sql内容为空

ClientDataSet1.Close;  
ClientDataSet1.CommandText:=edit1.Text;//即sql内容  
ClientDataSet1.Open;  

对于没有应用服务器设置filter 如:country like 'A%',filtered=true可实现sql功能。

(2)有参数

如服务端query的sql为

select * from animals

where name like :dd

则:客户端ClientDataSet

var  
     pm:Tparam;  
begin  
     ClientDataSet1.Close;  
     ClientDataSet1.ProviderName:='DataSetProvider1';  
     pm:=Tparam.Create(nil);  
     pm.Name:='dd';  
     pm.DataType:=ftString;  
     ClientDataSet1.Params.Clear;  
     ClientDataSet1.Params.AddParam(pm);  
     ClientDataSet1.Params.ParamByName('dd').AsString:=edit1.Text ;  
     ClientDataSet1.Open;  
     pm.Free;  
end;  

9、数据的更新管理

(1)savepoint 保存目前为止数据状态,可以恢复到这个状态

var  
     pp:integer;  
begin  
     pp:=ClientDataSet1.SavePoint;  
     ClientDataSet1.Edit;  
     ClientDataSet1.FieldByName('姓名').asstring:='古话';  
     ClientDataSet1.Post;  
     table1.Refresh;  
end;  

恢复点 : ClientDataSet1.SavePoint:=pp;

(2)Cancel,RevertRecord

取消对当前记录的修改,只适合没有post的,如果post,调用 RevertRecord 。

(3)CancelUpdate

取消对数据库所有的修改

(4)UndoLastChange(boolean),changecount

取消上一次的修改,可以实现连续撤消。参数为true:光标到恢复处;false:光标在当前位置不动。changecount返回修改记录的次数,一个记录修改多次,返回只一次,但UndoLastChange只撤消一次。

10、可写的recno

对于Ttable和Tquery的recno是只读的,而TClientDataSet的recno可读可写ClientDataSet1.recno:=5;是设第五个记录为当前记录。

11、数据保存

对于table使用post可更新数据,而ClientDataSet1的post只更新内存数据,要更新服务器数据要使ApplyUpdates(MaxErrors: Integer),他有一个参数,是允许发出错误的次数,-1表示无数次,使用simpleobjectbroker时常设为0,实现自动容错和负载平衡。