delphi 新版内存表 FDMemTable

news/2024/11/16 15:18:47/文章来源:https://www.cnblogs.com/Thenext/p/18549376

c++builder XE

官方demo最全60多个

http://community.embarcadero.com/blogs?view=entry&id=8761

 

 FireDAC.Comp.Client

 

用好FDMemTable代替之前的ClientDataSet,以前ClientDataSet内存表转换太繁琐了步骤。

 TClientDataSet *cds = new TClientDataSet(this);
  DataSetProvider1->DataSet = dm->ADOQueryPub;
  cds->ProviderName = "DataSetProvider1";
  cds->Open();

 

c++智能指针

 #include <memory>       //For STL auto_ptr class

std::auto_ptr<TFDMemTable> table (new TFDMemTable(NULL));

for (table->First(); !table->Eof; table->Next())

{

table->FieldByName("aa")->AsString;

}

 

一句就可以了

FDMemTable1->CopyDataSet(dm->ADOQueryPub, TFDCopyDataSetOptions() << coStructure << coRestart << coAppend);

 

多用FDMemTable,不再用ClientDataSet\DataSetProvider1做转换了

FDMemTable2->Data = FDMemTable1->Data;

FDMemTable2->CopyDataSet(FDMemTable1, TFDCopyDataSetOptions() << coStructure << coRestart << coAppend);

 

建立缓存表

复制代码
FDMemTable1.Close();
FDMemTable1.FieldDefs.Clear();
FDMemTable1.FieldDefs.Add('ID', ftInteger, 0, True);
FDMemTable1.FieldDefs.Add('Name', ftString, 20, false);
FDMemTable1.CreateDataSet();
FDMemTable1.AppendRecord([101, 'aaa']);
FDMemTable1.AppendRecord([102, 'bbb']);
FDMemTable1.AppendRecord([103, 'ccc']);
复制代码

 

0)FDMemTable1.SourceView遍历各行数据,取任意行数据无需Next移动指针了。TFDDatSView

 for (int i = 0; i < FDMemTable1->SourceView->Rows->Count; i++)
 {
  Caption = FDMemTable1->SourceView->Rows->ItemsI[i]->GetData(1);
 }

FDMemTable1->SourceView->Rows->ItemsI[i]->GetData("fieldName");//取指定行指定字段名的值
 }

9行7列的值。

 FDMemTable1.Data.DataView.Rows.ItemsI[9].ValueI[7];

 FDMemTable1.Table.Rows[i].ValueI[oCol.Index]

 Caption = FDMemTable1->SourceView->Rows->Count;//过滤后1条
 Caption = FDMemTable1->Table->Rows->Count;//过滤无效,全部记录3条

 

iMax := 0;
for i := 0 to FDQuery1.SourceView.Rows.Count - 1 doif FDQuery1.SourceView.Rows[i].GetData('id', @iVal) and (iVal > iMax) theniMax := iVal

 

数据集拷贝,复制数据集,合并数据集

 FDMemTable1->Filter = "id=102";
 FDMemTable1->Filtered = true;

FDMemTable1只有1条记录

 1)Data

FDMemTable2->Data = FDMemTable1->Data;

 

FDQuery->Open("select * from tt");

FDMemTable2->Data = FDQuery->Data;

 

FDMemTable2是全部记录,有3条记录。

FDMemTable1->Delete();后的记录不在Data里。

 2)CopyDataSet

带结构拷贝

FDMemTable2->CopyDataSet(FDMemTable1, TFDCopyDataSetOptions() << coStructure << coRestart << coAppend);

 FDMemTable2->CommitUpdates();

缓存更新用到changeCount,所以copy完后加上CommitUpdates

 

不带结构,仅拷贝数据,字段个数可以不一致,字段数以目标数据集FDMemTable2为标准。

FDMemTable2->CopyDataSet(FDMemTable1, TFDCopyDataSetOptions() <<  coRestart << coAppend);

//第二个参数默认是coRestart << coAppend,所以下面就更简单了。

FDMemTable2->CopyDataSet(FDMemTable1);

FDMemTable2只有1条记录

 3)CopyRecord\CopyField

copy the current record field values .Only One Record

  FDMemTable2->CopyDataSet(FDMemTable1, TFDCopyDataSetOptions() << coStructure);
 FDMemTable2->Edit();
 FDMemTable2->CopyRecord(FDMemTable1);

 4)CloneCursor

All Record, ignore filter

CloneCursor,数据共享,一个修改,另一个也修改了,但是FDMemTable1->Close之后FDMemTable2还正常显示。

FDMemTable2->CloneCursor( FDMemTable1);

 2016.3.4 test 不能排序,FDMemTable2->IndexFieldNames = "ID";不起作用,所以尽量不建议用这个方式。

5)AtrachTable

All Record,ignore filter,TFDDatSTable

 FDMemTable2->AttachTable(FDMemTable1->Table, NULL);

//or

//FDMemTable2->AttachTable(FDMemTable1->Table,FDMemTable1->View);
 FDMemTable2->Open();

6)FilteredData

FDQuery1.Filter := 'upper(name) like ''D%''';
FDQuery1.Filtered := True;
// copy to FDMemTable1 all FDQuery1 visible (where name starts from D) records
FDMemTable1.Data := FDQuery1.FilteredData;

RecordCount是过滤后的记录数。过滤前有100行,过滤后有5行,那么RecordCount就是5
FDQuery1->Data是100行,FilteredData是5行的数据
7)XMLData
All Record ignore filter
 Memo1->Text = FDMemTable1->XMLData;
 FDMemTable2->XMLData = Memo1->Text;

FDMemTable1->ChangeCount,
通过Data赋值,默认全部记录都是修改过的,也就是ChangeCount=RecordCount,有100条记录,获取ChangeCount属性就是100.这样合适还是不合适呢?
FDMemTable1->Data = FDQuery->Data;
FDMemTable1->CancelUpdates();或者FDMemTable1->CommitUpdates();
加上CancelUpdates这句话,ChangeCount就正常了!!反应真实的修改记录数。
Append的记录需要把属性CachedUpdates设为true,ChangeCount就正确了。
8)Delta
IFDDataSetReference类型

FDMemTable2->Delta= FDMemTable1->Delta;

ADMemTable1.FilterChanges := [rtModified, rtInserted, rtDeleted];
ADMemTable1.Data := ADQuery1.Delta;

9)查看删除过的记录UpdateStatus

FDMemTable想要找到并显示删除的记录
FDMemTable1->Delete();
   FDMemTable2->FilterChanges << Firedac::Comp::Dataset::rtDeleted;
   FDMemTable1->Data = FDMemTable1->Data;
while (!FDMemTable1.eof)
{
if( table->UpdateStatus() == usDeleted)
...
}
默认是不显示删除过的记录的,FilterChanges不包括rtDeleted属性。
10)分页及加载全部页
FetchOptions的Mode默认是fmOnDemand表示分页,每页50,改为fmAll表示全部记录。
分页TFDFetchOptions.RowsetSize
FetchNext
FetchAll
FetchOptions.RecordCountMode property

FDQuery1.Open;
FDQuery1.FetchAll;//必须加这一句,否则数据集不全。
FDMemTable1.Data := FDQuery1.Data;
用了grideh,为何导致分页不灵了???全部记录出来了?field设置了ftsum导致,不设置每次就50行记录。

LocateEx

11)增强的Locate功能LocateEx、LookupEx函数

lxoCheckOnly  If included, then LocateEx does not:
Change the current position. Fire BeforeScroll / AfterScroll events. Finish editing mode
不改变位置和编辑状态的搜索,强大!

   if (ds1->LocateEx("DM", "001", TFDDataSetLocateOptions() << lxoCheckOnly))
12)刷新数据集
query1.Refresh();

13)只读字段
select '' as temp,flag=0,sql返回的虚拟字段,以前clientDataSet可以修改,FDMemTable里不能改了。
ClientDataSet1->FieldByName("flag")->AsString="1";
但是FDMemTable不能改了。怎么办?以前的这种虚拟字段的方式挺好用啊。
解决办法:设置属性TFDMemTable.UpdateOptions.CheckReadonly=true

14)主从表关系
第一步:
fdqueryDetail.MasterSource := DataSource1;
第二步:
fdqueryDetail.MasterFields := 'OrderNo'; { 多个字段时用分号隔开 }
或者
fdqueryDetail.sql.text='select * from OrderDetail where OrderMasterKey=:OrderMasterKey';

两个FDMemTable做主从怎么不起作用呢?

15)过滤数据FilterChanges
只显示修改后的数据
ClientDataSet1->FilterChanges = TFDUpdateRecordTypes() << Firedac::Comp::Dataset::rtModified;

ClientDatSet用Grideh可以排序,添加EhLibCDS.pas文件即可。
TFDMemTable添加EhLibFireDAC.pas怎么不起不能排序,报错TFDMemTable is not SQL based dataset,FDQuery排序可以了
把SortLocal=true,也不能排序,报错 TSQLDatasetFeaturesEh can not sort data in dataset "FDMemTable1" in local mode
TFDMemTable不能排序,ClientDatSet替换为TFDMemTable的进程又得延缓.
比较和跟踪源码,Delphi里TFDMemTable排序正常。c++builder新建一个工程添加内存表和数据也排序正常。

最终解决了,原来是旧的ehlib控件卸载不干净,原来的工程里还有路径和ehlib.lib文件的链接,清除后排序全部OK!

2019.4.1 一个界面A 排序报错TFDMemTable is not SQL based dataset,弹出窗口排序正确,为什么呢,
FDQuery.Fields.DataSet ?这也是数据集?
Data.DB.TFields.DataSet
Identifies the dataset to which a TFields object belongs.
 A DataTable or a DataView must be supplied. Hint: if that is TFDMemTable, use CreateDataSet or CloneCursor to open dataset

TFDDataSet 基类

fdquery,dbgrideh控件的ftsum字段求和影响

C++Builder 返回数据集
_di_IFDDataSetReference

16)已有数据的FDMemTable添加列,动态添加列
原有数据集,现有数据集,现有字段,原有字段,添加新增选择列

  FDMemTable2.FieldDefs := FDMemTable1.FieldDefs;
  FDMemTable2.FieldDefs.Add('Test', ftString, 20 { , False } ); // default parameter
  FDMemTable2.FieldDefs.Find('Test').Index := 0;
  FDMemTable2.CreateDataSet; // or just Open that sets Active to true;
  FDMemTable2.CopyDataSet(FDMemTable1);

17)缓存更新
FDMemTable1->ChangeCount
执行了ApplyUpdates或CommitUpdates后ChangeCount变为0
FDMemTable1->ApplyUpdates(0);

C++builder Berlin //Berlin 排序无效 2017.3.12
delphi正常

升序
self.FDMemTable1.IndexFieldNames := 'ID:A';

降序
self.FDMemTable1.IndexFieldNames := 'ID:D';

FDMemTable1->IndexFieldNames = "ID:D";


FDMemTable1->CloneCursor(m->dsModule, true, true);
CloneCurso的数据集均无法用IndexFieldNames排序。用CreateDataSet创建的数据集排序正常!

Data赋值、CopyDataSet后的数据集均排序可以正常。建议不用CloneCursor。


18.修改只读字段
query1.UpdateOptions.AssignedValues = [uvCheckReadOnly]
    FDStoredProc1->UpdateOptions->CheckReadOnly = false;

TSQLTimeStampField
ClientDataSet1: Type mismatch for field 'ffdatetimie', expecting: DateTime actual: TimeStamp
TDateTimeField
TDateTime 替换为
TSQLTimeStampField

FMTBcd
ds1: Type mismatch for field 'UNITPRICE', expecting: Float actual: FMTBcd.
TFloatField *ds1UNITPRICE;
TBCDField
替换为
TFMTBCDField

[Amount] numeric(18,0)   TFMTBCDField
[PhPrice] decimal(18,4)  TBCDField
ff3 decimal(18,3) TFMTBCDField
可能fdquery认为4位小数就设计器添加到字段列表是TBCDField,非4位小数就是TFMTBCDField,包括0 1 2 3 位小数。
19.建立索引

  FDQueryRelation.AddIndex('index1','ITEMTYPE;ITEMNOHIS','', []);

  FDQueryRelation.IndexName := 'index1';

经过试验证明,filter没有使用索引,支持like表达式
  locate和findkey使用了索引,精确定位,要求检索速度快,检验使用
Caching_Updates_

http://docwiki.embarcadero.com/RADStudio/Rio/en/Caching_Updates_(FireDAC)
FDQuery1.CachedUpdates := True;
iSavePoint := FDQuery1.SavePoint;
tryFDQuery1.Append;...FDQuery1.Post;FDQuery1.Append;...FDQuery1.Post;FDQuery1.Append;...FDQuery1.Post;
exceptFDQuery.SavePoint := iSavePoint;
end;


FDQuery1.CachedUpdates := True;
FDQuery1.Append;
...
FDQuery1.Post;
FDQuery1.Append;
...
FDQuery1.Post;
FDQuery1.Append;
...
FDQuery1.Post;
FDConnection1.StartTransaction;
iErrors := FDQuery1.ApplyUpdates;
if iErrors = 0 then beginFDQuery1.CommitUpdates;FDConnection1.Commit;
end
elseFDConnection1.Rollback;


varoErr: EFDException;
...
if FDQuery1.ApplyUpdates > 0 then beginFDQuery1.FilterChanges := [rtModified, rtInserted, rtDeleted, rtHasErrors];tryFDQuery1.First;while not FDQuery1.Eof do beginoErr := FDQuery1.RowError;if oErr <> nil then begin// process exception object...end;FDQuery1.Next;end;finallyFDQuery1.FilterChanges := [rtUnmodified, rtModified, rtInserted];end;
end;
19)AppendData
2个完全一样的数据集合并 AppendData
ADOQuery1->AppendData(ADOQuery2->Data );
不用循环遍历了,一行命令搞定


void __fastcall Tfrm::ds1UpdateError(TDataSet *ASender, EFDException *AException,
          TFDDatSRow *ARow, TFDUpdateRequest ARequest, TFDErrorAction &AAction)

{
throw new Exception(  AException->Message );
}

20.fdmemtable批量编辑性能优化
http://docwiki.embarcadero.com/RADStudio/Rio/en/TFDMemTable_Questions
例如 Set the following properties LogChanges, FetchOptions, ResourceOptions, and UpdateOptions.
FDMemTable1.LogChanges := False;FDMemTable1.FetchOptions.RecsMax := 300000;  //Sample valueFDMemTable1.ResourceOptions.SilentMode := True;FDMemTable1.UpdateOptions.LockMode := lmNone;FDMemTable1.UpdateOptions.LockPoint := lpDeferred;FDMemTable1.UpdateOptions.FetchGeneratorsPoint := gpImmediate;

Then surround massive edition operations into BeginBatch / EndBatch method calls:

  FDMemTable1.BeginBatch;tryfor i := 1 to 1000 do beginFDMemTable1.Append;// ...FDMemTable1.Post;end;finallyFDMemTable1.EndBatch;end;

c#
DataTable dataFee;
DataRow[] drRerr =   dataFee.Select("目录类别=''");

复制表有两种方法
DataTable.Clone() 只克隆表结构
DataTable.Copy() 克隆表结构及数据

解释
 
 
 DataTable dt2 = dt.Clone();
 var rows = dataFee.Select("col3>=30", "col3 desc");if (rows != null && rows.Length > 0)
  {
   foreach (DataRow row in rows)
    {
       dt2.ImportRow(row);
    }
   }
FDConnection1一句话执行SQL
FDConnection1.ExecSQL('truncate table tab1');
FDConnection1.ExecSQL('drop table tab2', True);
FDConnection1.ExecSQL('delete from mytab where id > :p1', [1000]);
FDConnection1.ExecSQL('update mytab where id = :p1 set blobfld = :blb',[1000, StringOfChar('x', 100000)], [ftInteger, ftBLOB]);

多表查询更新

解释
 
 
 FDQuery1->UpdateOptions->UpdateTableName="T_USER_B";//联合查询 更新指定的表FDQuery1->FieldByName("NAME")->ProviderFlags.Clear();//不更新该字段克隆
      FClonedDataSet := Table.FDataSet.GetClonedDataSet(True);
    if FClonedDataSet = nil then begin
      FClonedDataSet := TFDMemTable.Create(nil);
      TFDMemTable(FClonedDataSet).CopyDataSet(Table.FDataSet, [coStructure, coCalcFields,
        coRestart, coAppend, coIndexesCopy, coConstraintsCopy, coAggregatesCopy]);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/834627.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

理想雪 - 翠鸟协会

写在前面3844 字 | 小说 | 热爱 | 思考 | 表达 | 坚定 | 证明 | 坚守《理想雪》系列故事均为架空世界观,所有人名、地名等与现实世界无任何关联。该系列只且仅只为了说明,小说作者在该情境下会诞生的想法和采取的行动,以及背后的世界观、价值观和人生观。因此将具有强烈的个…

专题课:综合案例5

评委打分解答: 1.首先肯定要键盘录入6个评委的分数6个评委的分数,即6个变量,我们肯定用数组更加方便,因为后面求和求最大值之类的,用数组都更简单 遍历数组,我们每键盘打出一个元素就将其放入数组中 . 2.然后定义求和变量,将6个分数求和3.for循环搭配if筛选求最大、最小…

# 20222403 2024-2025-1 《网络与系统攻防技术》实验六实验报告

1.实验内容 本实践目标是掌握metasploit的用法。 指导书参考Rapid7官网的指导教程。 https://docs.rapid7.com/metasploit/metasploitable-2-exploitability-guide/ 下载官方靶机Metasploitable2,完成下面实验内容。 (1)前期渗透 ①主机发现(可用Aux中的arp_sweep,search一…

_app搭建笔记

逍遥模拟器端口号:21503 (3)adb install +包名的绝对路径 安装apk包 案例:adb install E:\dcs\two\app\mojibase.apk E:\dcs\two\app\baiduyuedu_5520.apk (4)活动路径名: aapt d badging D:\app\baiduyuedu_3760.apk(5)adb uninstall 包名:卸载 com.baidu.yued…

20222323 2024-2025-1 《网络与系统攻防技术》实验六实验报告

1.实验内容 掌握metasploit的用法。 下载官方靶机Metasploitable2,完成下面实验内容。 (1)前期渗透 ①主机发现(可用Aux中的arp_sweep,search一下就可以use) ②端口扫描:可以直接用nmap,也可以用Aux中的portscan/tcp等。 ③选做:也可以扫系统版本、漏洞等。 (2)Vsft…

InDesign 2025 for Mac(Id2025)最新激活版20.0.0

InDesign 2025具备强大的功能和灵活的扩展性,支持插件扩展,用户可以根据自身需求自定义工具和工作流程。在处理复杂排版和多页面设计时,InDesign 2025注重用户界面的友好性与功能的直观性,即使是新手用户也能快速上手。 InDesign 2025增强了多模态图文编辑能力,使得图像与…

【跟着阿舜学音乐-笔记】1.12和弦功能与进行原理

七和弦 七和弦是三和弦的基础上叠加三音构成的和弦(四个音的和弦)。其中小大七和弦(CmM7)很少运用,因为调内没有小大七和弦,同时听感上也不是很好。 注:有另一种和弦命名方式,即三和弦与根音呈大小七度的音组成和弦的命名法,该命名法对比上述命名法有个特例——增大七…

看过这个,你可能更了解指针一点(2)

先来看下图你认为以下的打印的结果是什么? 接下来,我们先来分析 ****在1中arr单独放在sizeof内表示整个数组, 因此计算的为整个数组大小。即6乘1得到6 1的答案为6 ****在2中arr没有被单独放在sizeof中, arr此时表示数组首元素的地址,+0则表示计算的是第一个元素地址的大小,…

stoi函数介绍

stoi 是 C++ 标准库中的一个函数,定义在头文件 <string> 中,它用于将字符串转换为整数类型。 函数原型 int stoi(const std::string& str, size_t* idx = 0, int base = 10);str(必选):要转换的字符串,必须以数字开头(可以包含正负号)。 插一句题外话 如果不…

数据采集与融合技术-第四次实践作业

gitee链接:作业4 作业①: 要求: 熟练掌握 Selenium 查找HTML元素、爬取Ajax网页数据、等待HTML元素等内容。 使用Selenium框架+ MySQL数据库存储技术路线爬取“沪深A股”、“上证A股”、“深证A股”3个板块的股票数据信息。 候选网站:东方财富网:http://quote.eastmoney.co…

团队作业4——项目冲刺-第六篇

团队作业4——项目冲刺-第六篇这个作业属于哪个课程 <计科22级34班>这个作业要求在哪里 <作业要求>这个作业的目标 修改完善需求规格说明书、系统设计、Alpha任务分配计划、测试计划GitHub 链接 https://github.com/tangliweiwww/ChatGpt🍟一、团队 1.团队名称:…

20222306 2024-2025-1 《网络与系统攻防技术》实验五实验报告

1.实验内容 (1)从www.besti.edu.cn、baidu.com、sina.com.cn中选择一个DNS域名进行查询,获取如下信息:DNS注册人及联系方式 该域名对应IP地址 IP地址注册人及联系方式 IP地址所在国家、城市和具体地理位置 PS:使用whois、dig、nslookup、traceroute、以及各类在线和离线工…