ClientDataSet的用法(转) - CNQCJ 的Delphi 博客 - 博客园
- 格式:doc
- 大小:18.67 KB
- 文档页数:18
ClientDataset的使用ClientDataset的使用嵌套ClientDataset:1: 当ClientDataset.packetRecords=-1时,不论客户端的ClientDataset.fetchOnDemand和服务端的DatasetProvider.FetchDetailOnDemand如何设置均会导致速度下降到难以忍受。
1.1原因解析:因为服务端datasetProvider指向的主表Dataset 会在刚打开时就为每一条纪录整理其Detail数据(循环发送Sql语句到数据库,并cache到子表的dataset,供以后的Filter使用)。
所以服务端的Dataset打开会非常慢。
1.2:解决方案:只有返回一条以编辑或增加一条主表纪录时才使用嵌套ClientDataset。
其他浏览时应动态刷新Detail控件。
1.3或者设定ClientDataset.packetRecords为一个比较小的值(100以内)。
1.3 clientdataset的fetchonDemand属性。
基本不影响速度(它不影响无服务端封装Detail的行为)。
它只设定clientdataset.next时是否自动GetNextPacket.1.4 DatasetProvider.FetchDetailOnDemand;使用Table作为子表会影响一倍左右的速度(1条主表纪录对应平均4条子表纪录时。
使用query作子表时速度基本一样。
)1.5 不论ClientDataset.packetRecords如何设置,服务端的主表qry都从数据库中一次取出全部纪录。
1.6 慎用ClientDataset.IndexName,它会导致读入所有纪录到客户端。
2、结论:对于存在主子表显示或编辑要求的客户端需要使用PacketRecords属性设为较小值。
(此类客户端一般不会要求显示太多数据)。
可以将服务端的DatasetProvider.FetchDetailOnDemand设置为false影响不大,还可简化客户端代码。
ClientDataSet的用法(转)-CNQCJ的Delphi博客-博客园ClientDataSet的用法(转)TClientDataSet控件继承自TDataSet,其数据存储文件格式扩展名为 .cds,是基于文件型数据存储和操作的控件。
该控件封装了对数据进行操作处理的接口和功能,而本身并不依赖上述几种数据库驱动程序,基本上能满足单机"瘦"数据库应用程序的需要。
1.TClientDataSet的基本属性和方法介绍1).FieldDefs: 字段定义列表属性开发者可通过单击属性编辑器中该属性编辑按钮,或在该控件上单击右键选择弹出菜单中的"Fields Editor"菜单进行字段编辑。
设置完此属性后,实际上就相当于定义了表的结构;如果想装入已有的数据表的结构和数据,可通过单击右键选择弹出菜单中的"Assign Local Data"菜单,从弹出对话框中选取当前窗体中已与数据库连接好的数据集控件名称即可(当前窗体中必须已放置好要套用的数据集控件并打开激活)。
使用注意:对于自定义的字段名表,该属性编辑完后,该控件仍然无法打开。
必须右键单击该控件,选择弹出菜单中的"Create DataSet"菜单,让该控件以上述编辑的字段列表为依据,创建数据集后,才能够被激活打开和使用。
否则,会出现类似"ClientDataSet1: Missing data provider or data packet."的错误(包括在运行期,运行期可调用该控件的CreateDataSet方法,从而动态定义字段和表)。
2).FileName属性说明:数据存储文件的名称。
因该控件是基于文件型的数据操作控件,因此,必须指定所操作的数据文件名称(默认扩展名称.cds),从而打开和激活该控件,进而进行数据编辑。
例1:利用此属性打开指定的.cds文件varPath: string;beginPath := ExtractFilePath(Application.ExeName); //取得可执行文件路径CDataSet1.FileName := Path + 'test.cds';CDataSet1.Open;end;3).CreateDataSet方法说明:该方法以FieldDefs中的字段名表为结构建立数据集,常用来进行动态定义表。
Delphi三层开发小技巧:TClientDataSet的Delta妙用Delphi做三层开发时,很多人都会在客户端放一个TClientDataSet,中间层远程数据模块就对应放一个TDataSetProvider,然后再连起来.其实这种方法很烦琐,而且程序痈肿不甘,不好维护.我们都知道TClientDataSet的Delta属性记录了数据的所有修改,应用它我们就可以方便的实现一个单表更新的通用方法.首先,在中间层添加一个方法,就叫ApplyUpdates吧.方法定义如下:function ApplyUpdates(const UpdateTable:String;Delta:Variant;out err:String):Boolean;参数UpdateTable是指要更新的表名,Delta是指传过来的TClientDataSet的Delta属性,如果更新错误err返回错误的内容.下面实现这个方法,首先在DataModule上放一个Query,Query连上Connection,然后再放一个TDataSetProvider连Query.代码如下:function TRoDm.ApplyUpdates(const UpdateTable:String;Delta:Variant;out err:String):Boolean;const sql='select * from %s where 1<>1';var sqlstr:string;ErrCount:Integer;beginResult:=False;sqlstr:=Format(sql,[UpdateTable]);tryConn.BeginTrans;Query.Close;Query.sql.text:=sqlstr;Query.open;Provider.ApplyUpdates(Delta,-1,ErrCount);Result:=ErrCount=0;if Result thenmitTranselse Conn.RollbackTrans;excepton E:Exception dobeginConn.RollbackTrans;err:=E.Message;end;end;end;到此,通用的更新方法已经完成了.不过客户端的ClientDataSet还不能查询显示数据,因此,还要写一个查询方法:function QuerySQL(const sqlstr:string;out Data:Variant;outerr:String):Boolean;参数sqlstr就是要持行的查询语句,Data返回查询结果,错误时err返回错误消息QuerySQL实现代码如下:function TRoDm.QuerySQL(const sqlstr:string;out Data:Variant;out err:String):Boolean;beginResult:=False;tryQuery.close;Query.sql.text:=sqlstr;Query.sql.Open;Data:=Provider.Data;Result:=True;Excepton E:Exception doerr:=E.Message;end;end;到这里,中间层的代码已经完了,客户端的调用就简单了.比如客户端有个数据模块DM,上面放一个DcomConnection或者SocketConnection,名叫Conn.例如,我们现在要做一个商品管理的功能,在窗体上放一个TClientDataSet叫Cds,放DataSource,DBGrid等,设置好相应的属性.然后在窗体创建(Create事件)时查询回所有数据,代码如下:const sql='select * from xxxx';var Data:Variant;err:String;beginif Dm.Conn.AppServer.QuerySQL(sql,Data,err) thenCds.Data:=Dataelse MessageBox(self.handle,pchar('查询数据出错:'+err),'错误',MB_OK+MB_ICONERROR);end;然后还有"添加","修改","删除"按扭,代码都和我们平时操作一样,比如"添加"按扭的代码:cds.append;cds.fieldbyname('xxx').asinteger:=xxx;//....cds.post;修改,删除也这样写.不过现在还有个小问题是,这个表的主键的生成问题,这里我们不能用自增主键,要自己自己生成主键,这样你还得在中间层写一个中间层生成主键的方法,在"增加"按扭时生调用生成主键,然后再上面的操作.这里不再多说.增删改完后,这时的数据还在客户端的内存里,想保存到远程的中间层服务器就要用到我们刚才的方法了,下面就是"保存"按扭下的代码:var err:string;beginif cds.ChangeCount=0 then exit;//数据没改变就不用提交了if Dm.Conn.AppServer.ApplyUpdates('xxx',cds.Delta,err) then//xxx就是表名了beginMessageBox(self.handle,'保存成功!','提示',MB_OK+MB_ICONINFORMATION);cds.MergeChangeLog;//合并所有改变的数据end else MessageBox(self.handle,pchar('保存出错:'+err),'错误',MB_OK+MB_ICONERROR);end;到此,这篇文章也讲完了.用这个方法,那些单表的基础数据更新还可以写成一个祖先类,只要加一个取得更新表名的虚方法,比如:functionTableName:string;virtual;然后其后代只要override这个方法,返回各自的表名,其他的一句代码都不用写.scktsrvr.exe是一个NT的服务程序,你用scktsrvr.exe -install安装之后,每次系统启动,它都会自动运行的。
ListView在delphi中的常⽤⽤法ListView在delphi中的常⽤⽤法//增加i := ListView1.Items.Count;with ListView1 dobeginListItem:=Items.Add;ListItem.Caption:=IntToStr(i);ListItem.SubItems.Add('第'+IntToStr(i)+' ⾏');ListItem.SubItems.Add('第三列内容');end;//按标题删除for i:=ListView1.Items.Count-1downto0 Doif ListView1.Items.Caption = Edit1.Text thenbeginListView1.Items.Item.Delete(); //删除当前选中⾏end;//选中⼀⾏if ListView1.Selected <> nil thenEdit1.Text := ListView1.Selected.Caption;// listview1.Items[Listview1.Items.Count -1].Selected := True;// listview1.Items[Listview1.Items.Count -1].MakeVisible(True);//选择第⼀条procedure TForm1.Button2Click(Sender: TObject);beginlistview1.SetFocus;listview1.Items[0].Selected := True;end;//选择最后⼀条procedure TForm1.Button1Click(Sender: TObject);beginlistview1.SetFocus;listview1.Items[Listview1.Items.Count -1].Selected := True;end;//此为调⽤过程,可以任意指定要移动的Item,下⾯是当前(Selected)Itemprocedure ListViewItemMoveUpDown(lv : TListView; Item : TListItem; MoveUp, SetFocus : Boolean); varDestItem : TListItem;beginif (Item = nil) or((Item.Index - 1 < 0) and MoveUp) or((Item.Index + 1 >= lv.Items.Count) and (not MoveUp))then Exit;lv.Items.BeginUpdate;tryif MoveUp thenDestItem := lv.Items.Insert(Item.Index - 1)elseDestItem := lv.Items.Insert(Item.Index + 2);DestItem.Assign(Item);lv.Selected := DestItem;Item.Free;finallylv.Items.EndUpdate;end;if SetFocus then lv.SetFocus;DestItem.MakeVisible(False);end;ListViewItemMoveUpDown(ListView1, ListView1.Selected, True, True);//上移ListViewItemMoveUpDown(ListView1, ListView1.Selected, False, True);//下移TListView组件使⽤⽅法引⽤CommCtrl单元procedure TForm1.Button1Click(Sender: TObject);beginListView_DeleteColumn(MyListView.Handle, i);//i是要删除的列的序号,从0开始end;⽤LISTVIEW显⽰表中的信息:procedure viewchange(listv:tlistview;table:tcustomadodataset;var i:integer);begintlistview(listv).Items.BeginUpdate; {listv:listview名}trytlistview(listv).Items.Clear;with table do {table or query名}beginactive:=true;first;while not eof dobeginlistitem:=tlistview(listv).Items.add;listitem.Caption:=trim(table.fields[i].asstring);// listitem.ImageIndex:=8;next;end;end;finallytlistview(listv).Items.EndUpdate;end;end;ListView使⽤中的⼀些要点。
DelphiListView基本⽤法⼤全Delphi ListView基本⽤法⼤全//增加项或列(字段)ListView1.Clear;ListView1.Columns.Clear;ListView1.Columns.Add;ListView1.Columns.Add;ListView1.Columns.Add;ListView1.Columns.Items[0].Caption:='id';ListView1.Columns.Items[1].Caption:='type';ListView1.Columns.Items[2].Caption:='title';ListView1.Columns.Items[2].Width:=300;Listview1.ViewStyle:=vsreport;Listview1.GridLines:=true; //注:此处代码也可以直接在可视化编辑器中完成,也可写成以下这样beginwith listview1 dobeginColumns.Add;Columns.Add;Columns.Add;ViewStyle:=vsreport;GridLines:=true;columns.items[0].caption:='进程名';columns.items[1].caption:='进程ID';columns.items[2].caption:='进程⽂件路径';Columns.Items[0].Width:=100;Columns.Items[1].Width:=100;Columns.Items[2].Width:=150;endend;//增加记录with listview1.items.add dobegincaption:='1212';subitems.add('hh1');subitems.add('hh2');end;//删除listview1.items.delete(0);//从数据库表⾥读取数据写⼊ListviewvarTitem:Tlistitem; //此处⼀定要预定义临时记录存储变量. beginListView1.Items.Clear;with adoquery1 dobeginclose;sql.Clear;sql.Add('select spmc,jg,sl from kcxs');Open;ListView1.Items.Clear;while not eof dobeginTitem:=ListView1.Items.add;Titem.Caption:=FieldByName('spmc').Value;Titem.SubItems.Add(FieldByName('sl').Value); Titem.SubItems.Add(FieldByName('jg').Value);next;end;//删除ListView1.DeleteSelected;//如何取得ListView中选中⾏的某⼀列的值procedure TForm1.Button2Click(Sender: TObject);beginShowMessage(ListView1.Selected.SubItems.Strings[1]); //返回选中⾏第三列中的值end;showMessage(listView1.Selected.Caption); //返回选中⾏第⼀列的值.第1列的值: -->>> ListView1.Selected.Caption第i列的值(i>1):-->>> ListView1.Selected.SubItems.Strings[i]ListView1.Items.Item[1].SubItems.GetText); //取得listview某⾏某列的值Edit2.Text := listview1.Items[i].SubItems.strings[0]; //读第i⾏第2列返回选中⾏所有⼦列值.是以回车符分开的,你还要从中剥离出来你要的⼦列的值。
Delphi 中集合用法1. 概述在 Delphi 中,集合(Collections)是一种用来存储和操作多个数据元素的数据结构。
集合的使用可以提高代码的可读性和可维护性,并且提供了各种方便的方法,用于访问、添加、删除和搜索集合中的元素。
本文将介绍 Delphi 中集合的基本用法,并深入探讨集合的常见操作和性能优化技巧。
2. 集合类型Delphi 提供了多种集合类型,包括:2.1. TListTList 是 Delphi 中最常用的集合类型之一,它可以存储不同类型的元素,并且提供了各种方法用于对元素进行操作。
可以使用 Add 方法向 TList 中添加元素,使用 Delete 方法删除元素,使用 Count 属性获取元素数量,使用 IndexOf 方法查找元素等。
2.2. TObjectListTObjectList 是 TList 的一个变体,它专门用于存储 TObject 类型的元素。
TObjectList 继承自 TList,并且添加了一些针对对象操作的特定方法。
例如,可以使用 OwnsObjects 属性来控制对象是否在列表销毁时一同被销毁。
2.3. TStringsTStrings 是一个用于存储字符串的集合类型。
它是 TList 的一个子类,但专门用于存储字符串类型的元素。
TStrings 提供了一些方便的方法,用于对字符串进行操作,例如 Add、Delete、Insert、IndexOf 等。
2.4. TQueue 和 TStackTQueue 和 TStack 分别是队列和栈的实现,它们分别按照先进先出(FIFO)和后进先出(LIFO)的原则存储和访问元素。
TQueue 提供了 Enqueue 方法用于将元素添加到队列尾部,使用 Dequeue 方法从队列头部获取并移除元素。
TStack 提供了Push 方法用于将元素推入栈顶,使用 Pop 方法从栈顶获取并移除元素。
2.5. TDictionaryTDictionary 是一个用于存储键值对的集合类型,类似于 Delphi 中的字典或映射。
delphi datasetprovider 用法DataSetProvider 是 Delphi 中用于数据集的提供者组件。
它可以将数据集的数据提供给其他数据感知控件,如 DBGrid、DBNavigator 等。
DataSetProvider 的用法如下:1. 在 Delphi 的控件面板中找到 DataSetProvider 组件,并将其放置在窗体或数据模块中。
2. 使用对象控制台或属性编辑器来设置 DataSetProvider 的属性。
- DataSet:指定要提供数据的数据集。
可以是任何继承自TDataSet 的数据集,如 TTable、TQuery、TFDMemTable 等。
- Name:为 DataSetProvider 指定一个名称。
- Options:指定一些选项,如 poAllowCommandText、poAllowMetaData 等。
3. 针对所连接的数据集,设置 DataSetProvider 的事件。
- OnUpdateData:此事件在更新数据集时触发。
您可以在此事件中实现自定义的数据更新逻辑。
- BeforeUpdateRecord:此事件在更新数据集记录之前触发。
您可以在此事件中进行一些预处理操作。
- AfterUpdateRecord:此事件在更新数据集记录后触发。
您可以在此事件中执行一些后续处理操作。
- BeforeGetRecords:此事件在获取数据集记录之前触发。
您可以在此事件中进行一些预处理操作。
- AfterGetRecords:此事件在获取数据集记录后触发。
您可以在此事件中执行一些后续处理操作。
4. 连接数据感知控件到 DataSetProvider,使其能够使用提供的数据。
- 将一个 TDataSource 控件放置在窗体或数据模块中,将其DataSet 属性设置为 DataSetProvider。
- 将其他数据感知控件的 DataSource 属性设置为该 TDataSource 控件。
delphi cds.deleteindex的用法全文共四篇示例,供读者参考第一篇示例:Delphi是一种用于快速开发Windows应用程序的集成开发环境,它提供了许多方便的函数和组件来简化编程过程。
CDS (ClientDataSet)是Delphi中用于在客户端内存中存储和处理数据的组件。
在处理大量数据时,我们可能需要对CDS中的数据进行索引操作来提高查询和排序的效率。
在这种情况下,就需要使用CDS的DeleteIndex方法来删除指定的索引。
CDS.IndexFieldNames属性用于设置CDS中的排序规则,通过设置IndexFieldNames属性,我们可以实现根据指定字段进行排序。
当我们需要删除指定的索引时,可以使用DeleteIndex方法。
下面我们来看一下DeleteIndex方法的用法。
我们可以通过以下步骤来使用DeleteIndex方法:Step 1:设置要删除的索引名称我们需要确定要删除的索引的名称。
可以通过CDS.IndexName属性获取当前的索引名称,也可以通过CDS.IndexDefs属性获取所有索引的定义,从中选择要删除的索引。
Step 2:调用DeleteIndex方法接下来,我们可以调用DeleteIndex方法来删除指定的索引。
如果要删除名为“Index1”的索引,可以使用以下代码:CDS.DeleteIndex('Index1');Step 3:确认删除结果我们可以通过指定一个不存在的索引名称来验证删除操作是否成功。
如果DeleteIndex方法成功删除了索引,再次尝试访问这个不存在的索引将会触发错误。
在实际编程中,我们通常会在数据更新之前先删除旧索引,然后在更新后重新创建新索引,以保持数据操作的效率和一致性。
总结:DeleteIndex方法是Delphi中CDS组件的一个重要方法,可以帮助我们管理和优化数据操作。
通过删除不再需要的索引,可以提高程序的性能,减少资源的占用。
ClientDataSet的使用分享人:树军日期:2011/11/17问题描述:测试上阶联动,下阶联动,没有任何变化(B31-111020005)问题原因:排查问题后发现问题出现在数据集qryMPSTB过滤之后,使用next时,数据集并没有滚动到下一条,出问题的代码是:数据集在过滤之后,可以得到两条记录,但是过滤之后使用next时,并没有定位到下一条记录,最后查的原因是因为过滤的时候数据集的IndexFieldNames 是空值导致的,于是加上索引字段:基于以上问题,总结了下ClientDataSet的用法:1.利用Locate进行定位记录function Locate(const KeyFields: string; const KeyValues: Variant;Options: TLocateOptions): Boolean;其中Options参数可以是loCaseInsensitive和loPartialKeyloCaseInsensitive:不区分大小写loPartialKey:部分字符匹配用法例子:CdsBody1.Locate('LC002',mAccoutID,[loCaseInsensitive]) ;CdsBody1.Locate('Name',’李’,[ loPartialKey]) ;2.利用Filter进行过滤记录利用Filter可以在客户端进行过滤筛选记录,避免重新组SQL查询某一条件的记录用法例子:在使用Filter进行过滤记录时,确保clientdataset的IndexFieldNames属性具有值,否则过滤之后,使用first,next等浏览数据时将失效(B31-111020005)3.利用Delta获取数据集发生变化的记录数据集修改,新增,删除的记录都会记录在属性Delta中,可以利用此属性获取。
用法例子;同时可以利用ClientDataset的UpdateStatus方法获取本次数据集更新的种类,是新增的还是修改的,还是删除的usInserted:新增的记录usModified:修改的记录usDeleted:删除的记录4.利用CloneCursor复制数据集的数据和设置procedure CloneCursor(Source: TClientDataSet; Reset: Boolean;KeepSettings: Boolean = False); 利用CloneCursor可以复制另一个数据集的数据,还可以复制另一个数据集的设置,复制的设置有Filter,Filtered,IndexName,ReadOnly ,RemoteServer,ProviderName 等Reset 和KeepSettings 都是False ,则上面的属性都要设置成与源数据集相同Reset为True ,则上面的属性清空Reset为False 且KeepSettings 为True,上面的属性不变,数据操作对于两个数据集的作用相同用法例子:5.利用DATA属性仅复制数据集的数据这种用法常见于凭证中用法例子:6.利用DisableControls和EnableControls屏蔽刷新和进行优化用法例子:7.利用BookMark标记记录用法例子:8.利用FindField判断某个字段是否存在用法例子:。
DelphiXE7DataSnap学习第五章:提交clientdataset修改后的数据精品文章支持版本: D elphi XE7资源分类: 网络数据库发布平台: W indows转载地址: -介绍本文章介绍了Delphi XE7 DataSnap学习第五章:提交clientdataset修改后的数据,当我们通过datasnap读取到了数据,并显示到了clientdataset上面,然后我们就可以需要进行数据的修改,我们知道clientdataset是一个内存的数据集,所有修改后的记录都在clientdataset内存中,修改后的数据集可以通过下面的语句得到:ClientDataSet2.Delta。
现在我们就需要对ClientDataSet2.Delta这个数据进行处理,并得到sql脚本,然后提交到服务器,下面是主要的语句,主要是针对sqlserver开发的,如果是其他数据库可能需要稍微的调整,代码如下1.function GetStrContainCount(ASub: string; ASource: string):integer;2.begin3.Result := (Length(ASource) - Length(StringReplace(ASource,ASub, '',[]))) div Length(ASub);4.end;5.6.function StreamToHexStr(Stream: TStream): string;7.const8.csHexChar: array[0..15] of Char = '0123456789ABCDEF';9.var10. i, iCount, oldPos: Integer;11.begin12. Result := '';13. Stream.Position := 0;14. if Assigned(Stream) then15. begin16. oldPos := Stream.Position;17. iCount := Stream.Size - Stream.Position;18. SetLength(Result, iCount * 2);19. Stream.Read(Pointer(Result)^, iCount);20. for i := iCount downto 1 do21. begin22. Result[i * 2] := csHexChar[Byte(Result[i]) and $F];23. Result[i * 2 - 1] := csHexChar[(Byte(Result[i]) and$F0) shr 4];24. end;25. Stream.Position := oldPos;26. end;27.end;28.29.function BlobToHexStr(BlobField: TBlobField): string;30.var31. MemoryStream: TMemoryStream;32.begin33. MemoryStream := TMemoryStream.Create;34. try35. BlobField.SaveToStream(MemoryStream);36. Result := '0x' + StreamToHexStr(MemoryStream);37. finally38. MemoryStream.Free;39. end;40.end;41.42.function GetFieldValSQL(aField: TField): string;43.begin44. if aField.IsNull then45. Result := 'NULL'46. else47. begin48. case aField.DataType of49. ftString, ftWideString:50. begin51. Result := Trim(aField.AsString);52. if GetStrContainCount('"', Result) mod 2 <> 0then53. Result := Result + '"';54.55. if GetStrContainCount('`', Result) mod 2 <> 0then56. Result := Result + '`';57.58. Result := QuotedStr(Result);59. end;60. ftSmallint, ftInteger,61. ftWord, ftBCD, ftFloat: Result := aField.AsString;62. ftBlob: Result :=BlobToHexStr(TBlobField(aField));63. ftDateTime: Result :=QuotedStr(FormatDateTime('yyyy-mm-ddhh:nn:ss',aField.AsDateTime));64. ftDate: Result :=QuotedStr(FormatDateTime('yyyy-mm-dd',aField.AsDateTime));65. ftTime: Result :=QuotedStr(FormatDateTime('hh:nn:ss',aField.AsDateTime));66. else67. Result :=QuotedStr(aField.AsString);68. end;69. end;70.end;71.72.function GetUpDataSQLList(const sTableName,sKeyField:WideString;73. vDelta: OleVariant;lSQLList: TStringList; DefaultType:integer = 0): Integer;74.var75. P: TPSQLDefine;76. i,iStatus: integer;77. s1,s2,sSQL,iID: string;78. cdsUpdate: TClientdataset;79.begin80. Result := 0;81. iStatus := 0;82. if not VarisNull(vDelta) then83. begin84. cdsUpdate := TClientDataSet.Create(nil);85. cdsUpdate.Data := vDelta;86. cdsUpdate.DisableControls;87. try88. s1 := '';89. s2 := '';90. cdsUpdate.First;91. while not cdsUpdate.Eof do92. begin93. sSQL := '';94. case cdsUpdate.UpdateStatus of95. usUnmodified: s2 :=GetFieldValSQL(cdsUpdate.fieldbyname(sKeyField));96. usModified:97. begin98. s1 := '';99. for i := 1 to cdsUpdate.FieldCount do 100.begin101.if not cdsUpdate.Fields[i - 1].isNull then102.s1 := s1 + ',' + Trim(cdsUpdate.Fields[i - 1].FieldName) + '='103.+ GetFieldValSQL(cdsUpdate.Fields[i - 1]);104.end;105.if s1 <> '' then106.begin107. Delete(s1,1,1);108. sSQL := 'UPDATE ' + sTableName + ' SET ' + s1 + ' WHERE ' + sKeyField + '=' + s2;109.end;110.iStatus := 1;111.iID := S2;112.end;113. usInserted:114.begin115.s1 := '';116.s2 := '';117.iID := GetFieldValSQL(cdsUpdate.fieldbyname(sKeyField));118.for i := 1 to Cdsupdate.FieldCount do119.begin120.if not cdsUpdate.Fields[i - 1].isNull then121. begin122.s1 := s1 + ',' + Trim(cdsUpdate.Fields[i - 1].FieldName);123.s2 := s2 + ',' + GetFieldValSQL(cdsUpdate.Fields[i - 1]);124. end;125.end;126.if s1 <> '' then127. Delete(s1,1,1);128.if s2 <> '' then129. Delete(s2,1,1);130.if s1 <> '' then131. sSQL := 'INSERT INTO ' + sTableName + '(' + s1 + ') VALUES(' + s2 + ')';132.iStatus := 2;133.end;134. usDeleted:135.begin136.s2 := GetFieldValSQL(cdsUpdate.FieldByName(sKeyField));137.sSQL := 'DELETE FROM ' + sTableName + ' WHERE ' + sKeyField + '='+ s2;138.iStatus := 3;139.iID := S2;140.end;141.end;142.if sSQL <> '' then143.begin144. if DefaultType = 0 then145.lSQLList.Add(sSQL)146. else147. begin148.new(P);149.P.iStatus := iStatus;150.P.sSQL := sSQL;151.P.iID := iID;152.lSQLList.AddObject('', TObject(P));153. end;154.end;155.156.cdsUpdate.Next;157.end;158. finally159.FreeAndNil(cdsUpdate);160. end;161.end;162.end;复制代码然后通过调用上面的函数1.procedure TForm13.Button3Click(Sender: TObject);2.var3.lSQLList: TStringList;4.begin5.//6.7.ClientDataSet2.Edit;8.ClientDataSet2.FieldByName('c_title').AsString:='345345345';9.ClientDataSet2.Post;10.11. lSQLList:=TStringList.Create;12. GetUpDataSQLList('s_users','id',ClientDataSet2.Delta,lSQLList);13.14. showmessage(lSQLList.Text);15.end;复制代码显示出来的结果如下:图片上显示的是最后得到的sql语句,通过我提供的runsql功能就可以提交到服务器了。
delphi redisclient 用法Delphi RedisClient 用法详解什么是 RedisClient?RedisClient是Delphi中常用的Redis数据库访问组件,它提供了对Redis数据库的连接、读写操作以及常用的数据类型操作等功能。
下面将列举一些常用的RedisClient用法并进行详细讲解。
安装 RedisClient 组件在Delphi中使用RedisClient需要先进行组件的安装,具体步骤如下:1.在RedisClient的官方网站或其他可信源上下载安装包。
2.打开Delphi开发环境,选择”Component” -> “InstallPackages”。
3.点击”Add”,浏览到已下载的安装包,选择并点击”Open”。
4.在弹出的对话框中,选择RedisClient组件,点击”OK”进行安装。
连接到 Redis 数据库使用RedisClient连接到Redis数据库的代码示例:varRedis: TRedisClient;beginRedis := ;try:= '';:= 6379;;// 连接成功后的操作finally;end;end;以上代码示例中的和分别指定了Redis数据库所在的主机和端口号。
通过调用方法可以与Redis数据库建立连接。
写入和读取数据写入数据使用RedisClient写入数据的代码示例:varRedis: TRedisClient;beginRedis := ;try:= '';:= 6379;;['Key'] := 'Value'; // 写入字符串数据('HashKey', 'Field1', 'Value1'); // 写入哈希数据('SetKey', 'Value1', 'Value2'); // 写入集合数据// 其他写入操作...finally;end;end;以上示例代码演示了如何使用RedisClient写入字符串数据、哈希数据和集合数据,可以通过赋值或调用相应的写入方法实现。
ClientDataSet的排序要用到第三方控件DBGridEh,设置AutoSortMakertingprocedure DgbMainSortMarkingChanged(Sender: TObject);vari, j: integer;IndexFieldName, AFieldName, s: string;Desc: Boolean;begins := ''; //for i := 0 to DBGridEh.SortMarkedColumns.Count - 1 dobeginAFieldName := DBGridEh.SortMarkedColumns[i].FieldName;case (DBGridEh.SortMarkedColumns[i].Field.FieldKind) offkLookup, fkCalculated, fkAggregate: exit;end;Desc := DBGridEh.SortMarkedColumns[i].Title.SortMarker = smUpEh;if Desc thenIndexFieldName := 'i' + AFieldName + 'D'elseIndexFieldName := 'i' + AFieldName;j := ADataSet.IndexDefs.IndexOf(IndexFieldName);if j = -1 thenbeginwith ADataSet.IndexDefs.AddIndexDef dobeginName := IndexFieldName;Fields := AFieldName;//DescFields := AFieldName;if Desc thenOptions := [ixDescending];end;end;s := s + IndexFieldName;end;ADataSet.IndexName := s;end引入第二种方法KeyLife富翁笔记作者:hongxing_dl标题: ClientDataSet探讨(3)--排序关键字:分类:开发经验密级:公开ClientDataSet排序1、简单排序ClientDataSet1.IndexFieldNames:='排序字段'2、复杂排序(建立索引)下面这个过程仅供参考(因为用到三方控件DBGridEh):procedure TDM1.DsSort(SortColumn: TColumnEh);varOldIndex:string;beginif (SortColumn.Grid.DataSource=nil) or (SortColumn.Grid.DataSource.DataSet=nil) or (not SortColumn.Grid.DataSource.DataSet.Active) then Exit;OldIndex:=TClientDataSet(SortColumn.Field.DataSet).Index Name;if OldIndex<>'' thenbeginTClientDataSet(SortColumn.Field.DataSet).IndexName:='';TClientDataSet(SortColumn.Field.DataSet).DeleteIndex(OldI ndex);end;case SortColumn.Title.SortMarker ofsmNoneEh,smUpEh :TClientDataSet(SortColumn.Field.DataSet).AddInd ex('px',SortColumn.Field.FieldName,[ixDescending]);smDownEh:TClientDataSet(SortColumn.Field.DataSet).AddIn dex('px',SortColumn.Field.FieldName,[ixPrimary]);end;TClientDataSet(SortColumn.Field.DataSet).IndexName:='px';end;2003-11-5 12:09:00发表评语»»»2003-11-5 12:19:59 把上面的过程稍做修改,可用于标准DBGridvarASC:Boolean=True;//是否升序排列procedure TDM1.DsSort(SortColumn: TColumn);varOldIndex:string;beginif (SortColumn.Grid.DataSource=nil) or (SortColumn.Grid.DataSource.DataSet=nil) or (not SortColumn.Grid.DataSource.DataSet.Active) then Exit;OldIndex:=TClientDataSet(SortColumn.Field.DataSet).IndexName;if OldIndex<>'' thenbeginTClientDataSet(SortColumn.Field.DataSet).IndexName:='';TClientDataSet(SortColumn.Field.DataSet).DeleteIndex(OldI ndex);end;case ASC ofTure :TClientDataSet(SortColumn.Field.DataSet).AddIndex('p x',SortColumn.Field.FieldName,[ixDescending]);//已经是升序就按降序排列else//否则按升序排列TClientDataSet(SortColumn.Field.DataSet).AddIndex('px',Sor tColumn.Field.FieldName,[ixPrimary]);end;{end case}TClientDataSet(SortColumn.Field.DataSet).IndexName:='px';ASC:=not ASC;。
DELPHI分布式技术--ClientDataSet秦义江;赵青;刘建军【期刊名称】《内蒙古石油化工》【年(卷),期】2006(032)005【摘要】@@ TClientDataSet从类的继承关系上来看,是TDataSet这个抽象类的子类,所以我们可以在TDataSet这个抽象层次上对其进行我们熟悉的操作,比如导航、排序、过滤、编辑.要注意的是,TClientDataSet使用了一种全新的技术,它将所有的数据均放在内存中,所以TClientDataSet是个只存在内存中的"虚拟表",因此对数据库的操作是非常快的.与一般的数据集组件不同,TClientDataSet使用的技术比较特别,本着高速度、低存储需求的原则,TClientDataSet的内部使用了两个数据存储源.【总页数】1页(P60)【作者】秦义江;赵青;刘建军【作者单位】中原油田分公司采油二厂;中原油田分公司采油二厂;中原油田分公司采油二厂【正文语种】中文【中图分类】TE6【相关文献】1.用Delphi结合ADO开发Excel数据服务器应用技术(一)——Delphi结合ADO 的方法和数据连接 [J], 闫海忠2.基于ClientDataSet的数据库应用系统设计 [J], 张国权;彭江平3.dbExpress及ClientDataSet应用结构中异常处理研究 [J], 彭江平4.在ClientDataSet中动态创建查找字段的实现方法 [J], 刘铭;阮国龙5.Heavy Metals in Soft Tissues of Short-Beaked Common Dolphins(<i>Delphinus delphis</i>) Stranded along the Algerian West Coast [J], Larbi Doukara Kamel;Bouslah Yahia;Bouderbala Mohammed;Boutiba Zitouni因版权原因,仅展示原文概要,查看原文内容请购买。
delphi 中集合用法Delphi 中集合用法Delphi 是一种面向对象的编程语言,它提供了许多集合类来帮助开发人员管理数据。
在本文中,我们将介绍 Delphi 中常用的几种集合类及其用法。
一、TList 类TList 是 Delphi 中最常用的集合类之一。
它是一个动态数组,可以存储任意类型的数据。
以下是 TList 类的基本用法:1. 创建 TList 对象要创建 TList 对象,可以使用以下代码:varMyList: TList;beginMyList := TList.Create; // 创建一个空的 TList 对象end;2. 添加元素要向 TList 中添加元素,可以使用 Add 方法:MyList.Add('Hello');MyList.Add('World');3. 访问元素要访问 TList 中的元素,可以使用 [] 运算符或 Items 属性:varS: string;beginS := MyList[0]; // 获取第一个元素S := MyList.Items[1]; // 获取第二个元素end;4. 删除元素要从 TList 中删除元素,可以使用 Delete 方法:MyList.Delete(0); // 删除第一个元素5. 清空列表要清空整个列表,可以使用 Clear 方法:MyList.Clear;二、TStringList 类TStringList 是一个特殊的 TList 类,它只能存储字符串类型的数据。
以下是 TStringList 类的基本用法:1. 创建 TStringList 对象要创建 TStringList 对象,可以使用以下代码:varMyStringList: TStringList;beginMyStringList := TStringList.Create; // 创建一个空的 TStringList 对象end;2. 添加元素要向 TStringList 中添加元素,可以使用 Add 方法:MyStringList.Add('Hello');MyStringList.Add('World');3. 访问元素要访问 TStringList 中的元素,可以使用 [] 运算符或 Strings 属性:varS: string;beginS := MyStringList[0]; // 获取第一个元素S := MyStringList.Strings[1]; // 获取第二个元素end;4. 删除元素要从 TStringList 中删除元素,可以使用 Delete 方法:MyStringList.Delete(0); // 删除第一个元素5. 清空列表要清空整个列表,可以使用 Clear 方法:MyStringList.Clear;6. 排序列表要对整个列表进行排序,可以使用 Sort 方法:MyStringList.Sort;三、TObjectList 类TObjectList 是一个 TList 类的扩展版本,它只能存储 TObject 类型的数据。
delphi clientdataset.logchange使用方法关于Delphi ClientDataSet 的logchange 使用方法ClientDataSet 是Delphi 中非常重要的数据组件之一,它提供了对数据的临时存储、编辑、过滤、排序等操作。
在实际的软件开发中,我们经常需要对ClientDataSet 中的数据做出修改,并且需要记录下这些修改的历史,这就需要使用到logchange。
本文将详细介绍Delphi ClientDataSet 的logchange 使用方法,并给出一些示例代码,以方便读者理解和掌握。
第一步:引入相关的单元要使用ClientDataSet 的logchange 功能,首先需要引入相关的单元。
在Delphi 的使用过程中,有很多与数据库相关的单元,我们需要使用其中的DBClient 单元。
打开你的Delphi 项目,找到用到ClientDataSet 的单位,在用到ClientDataSet 的单位的uses 后面添加上DBClient 单元。
usesDBClient;第二步:打开logchange 功能ClientDataSet 的logchange 功能默认是关闭的,我们需要手动打开它。
在使用logchange 功能之前,可以在打开ClientDataSet 之后添加一行代码来开启logchange 功能。
示例如下:ClientDataSet1.CreateDataSet; 创建一个新的DataSetClientDataSet1.LogChanges := True; 打开logchange 功能第三步:记录数据修改的历史在开启了logchange 功能之后,ClientDataSet 就会自动记录数据的修改历史。
当我们对ClientDataSet 中的数据进行修改时,logchange 会将每一次修改都记录下来。
我们可以通过遍历logchange 来获取记录的修改历史。
delphi clientsocket 用法Delphi的ClientSocket组件是一个非常有用的网络通信组件,它允许你创建一个TCP/IP客户端,与远程服务器进行通信。
以下是使用Delphi的ClientSocket组件的基本步骤:1. 首先,在你的Delphi项目中添加一个TClientSocket组件。
你可以在工具箱中找到ClientSocket组件,然后将它拖放到你的窗体上。
2. 在TClientSocket的属性中,设置好连接的服务器地址和端口号。
你可以通过修改`Host`和`Port`属性来实现。
3. 添加事件处理程序来处理连接和通信过程中的事件。
TClientSocket有一些重要的事件,比如`OnConnect`,`OnDisconnect`,`OnRead`等等。
你可以在这些事件中编写你自己的代码来实现特定的功能。
例如,当连接成功建立时,`OnConnect`事件会触发,你可以在事件中执行相关操作。
下面是一个简单的示例代码,展示了如何使用Delphi的ClientSocket组件来连接服务器并进行通信:```delphiunit Unit1;interfaceuses// 导入所需的单元typeTForm1 = class(TForm)ClientSocket1: TClientSocket;Button1: TButton;Memo1: TMemo;procedure ClientSocket1Connect(Sender: TObject;Socket: TCustomWinSocket);procedure ClientSocket1Disconnect(Sender: TObject;Socket: TCustomWinSocket);procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);procedure Button1Click(Sender: TObject);private{ Private declarations }public{ Public declarations }end;varForm1: TForm1;implementation{$R *.dfm}procedure TForm1.ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket);beginMemo1.Lines.Add('Connected to server.');end;procedure TForm1.ClientSocket1Disconnect(Sender: TObject;Socket: TCustomWinSocket);beginMemo1.Lines.Add('Disconnected from server.');end;procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);beginMemo1.Lines.Add('Received: ' + Socket.ReceiveText);end;procedure TForm1.Button1Click(Sender: TObject);beginif not ClientSocket1.Active thenClientSocket1.Open; // 打开与服务器的连接end;end.```在上面的示例中,当点击Button1按钮时,会尝试与在TClientSocket的属性中指定的服务器建立连接。
ClientDataSet的用法(转)- CNQCJ 的Delphi 博客- 博客园ClientDataSet的用法(转)TClientDataSet控件继承自TDataSet,其数据存储文件格式扩展名为 .cds,是基于文件型数据存储和操作的控件。
该控件封装了对数据进行操作处理的接口和功能,而本身并不依赖上述几种数据库驱动程序,基本上能满足单机"瘦"数据库应用程序的需要。
1.TClientDataSet的基本属性和方法介绍1).FieldDefs: 字段定义列表属性开发者可通过单击属性编辑器中该属性编辑按钮,或在该控件上单击右键选择弹出菜单中的"Fields Editor"菜单进行字段编辑。
设置完此属性后,实际上就相当于定义了表的结构;如果想装入已有的数据表的结构和数据,可通过单击右键选择弹出菜单中的"Assign Local Data"菜单,从弹出对话框中选取当前窗体中已与数据库连接好的数据集控件名称即可(当前窗体中必须已放置好要套用的数据集控件并打开激活)。
使用注意:对于自定义的字段名表,该属性编辑完后,该控件仍然无法打开。
必须右键单击该控件,选择弹出菜单中的"Create DataSet"菜单,让该控件以上述编辑的字段列表为依据,创建数据集后,才能够被激活打开和使用。
否则,会出现类似"ClientDataSet1: Missing data provider or data packet."的错误(包括在运行期,运行期可调用该控件的CreateDataSet方法,从而动态定义字段和表)。
2).FileName属性说明:数据存储文件的名称。
因该控件是基于文件型的数据操作控件,因此,必须指定所操作的数据文件名称(默认扩展名称.cds),从而打开和激活该控件,进而进行数据编辑。
例1:利用此属性打开指定的.cds文件varPath: string;beginPath := ExtractFilePath(Application.ExeName); //取得可执行文件路径CDataSet1.FileName := Path + 'test.cds';CDataSet1.Open;end;3).CreateDataSet方法说明:该方法以FieldDefs中的字段名表为结构建立数据集,常用来进行动态定义表。
例2:动态创建一具有姓名和年龄两个字段的数据集。
//创建字段名表CDataSet.FieldDefs.Clear;with CDataSet.FieldDefs.AddFieldDef dobeginName := 'Name';Size := 10;DataType := ftString;end;with CDataSet.FieldDefs.AddFieldDef dobeginName := '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\desktop\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;2.使用TClientDataSet控件的应用程序发布的注意事项:如前所述,使用TClientDataSet控件的程序发布时不需要任何数据库驱动程序,大大节省了安装文件的大小。
但是,在发布程序时别忘了将Windows系统目录下midas.dll(257KB)与应用程序一起发布(运行必须),否则,程序仍然无法正常运行。
三、结束语通过使用Delphi中TClientDataSet控件,既实现了应用程序可彻底脱离数据库驱动程序,也实现了常规数据集控件简单易用的特性,为编写"瘦"数据库应用程序提供了一种技术方法和手段。
上述程序在Pwindows98,Delphi5下测试通过。
TClientDataSet在三层结构中,TClientDataSet的地位是不可估量的,她的使用正确与否,是十分关键的,本文从以下几个方面阐述她的使用,希望对你有所帮助.1.动态索引procedure TForm1.DBGrid1TitleClick(Column: TColumn); beginif (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.三层结构的公文包的实现方法同时设定1:filename(*.cds)2.remote server6.可以对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;mandText:=edit1.Text;//即sql内容ClientDataSet1.Open;对于没有应用服务器设置filter 如:country like 'A%'filtered=true可实现sql功能(2)有参数如服务端query的sql为select * from animalswhere name like :dd则:客户端ClientDataSetvarpm:Tparam;beginClientDataSet1.Close;ClientDataSet1.ProviderName:='DataSetProvider1';pm:=Tparam.Create(nil);:='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 保存目前为止数据状态,可以恢复到这个状态varpp:integer;beginpp:=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,实现自动容错和负载平衡====================================== ================影响ClientDataSet处理速度的一个因素TClientDataSet是Delphi开发数据库时一个非常好的控件。