标签: tclientdataset

16
推荐指数
1
解决办法
2万
查看次数

ClientDataset.RefreshRecord在Delphi XE中不再适用于连接表 - 任何解决方法?

尝试刷新连接到SQL语句中具有联接表的数据集的ClientDataset上的记录时,TClientDataset.RefreshRecord不再生成SQL的表连接部分.

因此,调用此方法会导致SQL错误"无效列名称"为不在主表中的每个字段.

这在Delphi 2010及更早版本中不是问题.

连接到TClientDataset的DBX4或BDE组件都会发生错误,因此很可能是TClientDataset代码更改出现问题.

要复制此问题:

在Delphi XE中创建一个只有一个表单的新应用程序,并在其上删除所需的数据库组件(TSQLMonitor,TSQLConnection,TSQLQuery,TDatasetProvider,TClientDataset,TDatasource和TDBGrid)并将它们相互绑定.

使用表连接创建一个简单的SQL语句,并将其放在TSQLDataset.SQL属性中.

SQL语句只包含两个字段 - 主表的键字段和连接表中的字段 - 例如伪代码:

Select 
  MainTable.IntegerKeyField
  , JoinedTable.JoinField
FROM MainTable
LEFT OUTER JOIN JoinedTable ON MainTable.LookupFieldID = JoinedTable.JoinKeyField
Run Code Online (Sandbox Code Playgroud)

将这两个字段添加为TSQLQuery和TClientDataset中的持久字段,其中包含pfInKey的关键字段的Provider Flag(如果不知道哪个字段是密钥,则RefreshRecord将不起作用,因此必须使用持久字段).

在表单上添加两个按钮 - 一个只打开Clientdataset,第二个按钮调用clientdataset.refreshrecord;

运行应用程序,按下按钮打开网格中的数据集和数据显示.

按"刷新记录"按钮,您将收到连接字段的SQL错误"无效列名称".

关闭应用程序,打开SQLMonitor日志并在Delphi生成的刷新记录SQL语句中,您将看到它没有包含表连接语句.

====

我真的很感激有关如何解决这个问题的任何想法.

sql delphi tclientdataset delphi-xe

15
推荐指数
1
解决办法
2151
查看次数

在DBGrid中移动列似乎移动附加的DataSet字段

我上周观察到了一些我没想到的事情,并将在下面描述.我很好奇为什么会这样.它是TDataSet类内部的东西,TDBGrid的工件还是别的东西?

打开的ClientDataSet中的字段顺序已更改.具体来说,我在使用FieldDefs定义其结构后通过调用CreateDatatSet在代码中创建了一个ClientDataSet.此ClientDataSet结构中的第一个字段是名为StartOfWeek的Date字段.不久之后,我编写的代码(假设StartOfWeek字段位于零位置,ClientDataSet.Fields [0])失败,因为StartOfWeek字段不再是ClientDataSet中的第一个字段.

经过一番调查后,我了解到ClientDataSet中的每个字段都可能在给定时刻出现在创建ClientDataSet时与原始结构不同的某个位置.我不知道这可能会发生,并且对谷歌的搜索也没有提到这种效果.

发生了什么不是魔术.这些字段本身并没有改变位置,也没有根据我在代码中所做的任何事情而改变.导致字段在物理上看起来改变ClientDataSet中位置的原因是用户已经更改了ClientDataSet附加到的DbGrid中的列的顺序(当然是通过DataSource组件).我在Delphi 7,Delphi 2007和Delphi 2010中复制了这个效果.

我创建了一个非常简单的Delphi应用程序来演示这种效果.它由一个包含一个DBGrid,一个DataSource,两个ClientDataSets和两个Buttons的表单组成.此表单的OnCreate事件处理程序如下所示

procedure TForm1.FormCreate(Sender: TObject);
begin
  with ClientDataSet1.FieldDefs do
  begin
    Clear;
    Add('StartOfWeek', ftDate);
    Add('Label', ftString, 30);
    Add('Count', ftInteger);
    Add('Active', ftBoolean);
  end;
  ClientDataSet1.CreateDataSet;
end;
Run Code Online (Sandbox Code Playgroud)

Button1,标记为Show ClientDataSet Structure,包含以下OnClick事件处理程序.

procedure TForm1.Button1Click(Sender: TObject);
var
  sl: TStringList;
  i: Integer;
begin
  sl := TStringList.Create;
  try
    sl.Add('The Structure of ' + ClientDataSet1.Name);
    sl.Add('- - - - - - - - - - - - - - - - - ');
    for i := 0 to ClientDataSet1.FieldCount - 1 do
      sl.Add(ClientDataSet1.Fields[i].FieldName); …
Run Code Online (Sandbox Code Playgroud)

delphi tclientdataset tdbgrid tdataset

12
推荐指数
1
解决办法
5418
查看次数

将数据从数据集结构移动到另一个数据库的更快方法(在TDatasetProvider中)

我有一个自定义的TDatasetProvider,允许为它提供的任何数据创建新的字段.

所以,假设您在原始数据集上获得了以下字段:

  • 顾客ID
  • 名称
  • 年龄

您需要使用显示位图在DBGrid上选择它.好吧,你可以,因为我的DSP可以添加一个调用Selected数据集数据的布尔字段.

我现在这样做的方式:

  1. 创建2个TClientDataset对象(Origin和Target)
  2. 在Origin中,我加载从InternalGetRecords方法的参数获得的数据(我覆盖它)
  3. 在Tar​​get中,我创建了从Origin数据集定义的fielddef,并添加了开发人员在设计时创建的fielddef
  4. 在Tar​​get上执行CreateDataset
  5. 并且,逐行(和逐个字段),我将数据从Origin数据库复制到Target数据集
  6. 最后,将Data变量作为InternalGetRecords的返回值返回.

我真的不知道是否有更优雅(和更快)的方式来做到这一点.有另一种(更快和/或更优雅)的方式来获得这个结果?

delphi tclientdataset tdatasetprovider

12
推荐指数
1
解决办法
1万
查看次数

MidasLib.dcu使应用程序变慢

我在一些客户端声明MidasLib以避免由Midas.dll引起的dll地狱.

下面的代码运行大约2350ms.如果我在使用中删除了MidaLib声明,它将在45毫秒内开始运行!!

data.xml文件使用TClientDataSet.SaveToFile方法保存,有5000条记录,大小约为600Kb.

有谁知道如何解释这种奇怪的行为?

我可以在Delphi XE2 upd 3和Delphi XE3 upd 2中确认问题.

谢谢.

program Loader;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  MidasLib,
  System.SysUtils,
  Winapi.Windows,
  Data.DB,
  Datasnap.DBClient;

var
  cds : TClientDataSet;
  start, stop : Cardinal;
begin
  cds := TClientDataSet.Create(nil);
  try
    start := GetTickCount;
    cds.LoadFromFile('c:\temp\data.xml');
    stop := GetTickCount;
    Writeln(Format('Time elapsed: %dms', [stop-start]));
  finally
    cds.Free;
  end;
end.
Run Code Online (Sandbox Code Playgroud)

delphi tclientdataset

12
推荐指数
1
解决办法
3869
查看次数

Delphi - TClientDataset线程安全吗?

我有一个在线程1中管理的TClientDataset.

在另一个线程中,我有一个克隆的TClientDataset图像.

我会遇到线程问题吗?

编辑

克隆的图像以只读模式使用.

delphi tclientdataset

10
推荐指数
3
解决办法
2973
查看次数

TDataset书签有效期多长时间?

在我正在工作的项目中,我有如下代码.

procedure TForm.EditBtnClick(Sender:TObject);
begin
  // Mark is form variable. It's private
  Mark = cdsMain.GetBookmark;
  // blabalbal
  .
  .   
  .
end;

procedure TForm.OkBtnClick(Sender:TObject);
var  
  mistakes: Integer;
begin
  //Validation stuff and transaction control
  //removed to not clutter the code
  If cdsMain.ChangeCount <> 0 then 
    mistakes := cdsMain.AppyUpdates(-1); 
  cdsMain.Refresh;
  try
    cdsMain.GotoBookmark(Mark);
    // Yes, I know I would have to call FreeBookmark
    // but I'm just reproducing 
  except
    cdsMain.First;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

就个人而言,我没有太多使用书签 - 除了重新定位我只移动光标位置的数据集(创建列表,填充字符串列表等).如果我Refresh,更新(特别是当过滤器可以使记录不可见),重新获取(Close/ Open)或修改数据集中的数据的任何操作时,我不使用书签.我更喜欢Locate使用主键(TClientDataset当然使用a …

delphi tclientdataset dbexpress

10
推荐指数
3
解决办法
5778
查看次数

如何强制客户端数据集重新计算计算和内部计算字段?

我有ClientDatSet一些fkInternalCalc领域.CDS与任何提供商均无关联; 而是它在飞行中填充.如何强制CDS重新计算所有"可计算"字段?我无法打电话,Refresh()因为没有提供商来刷新数据.我到目前为止唯一的方法是浏览所有记录,这不是最好的方法.

PS:我已经阅读了这个问题这篇文章,但我希望有一个更优雅的方式.

delphi tclientdataset delphi-xe2

10
推荐指数
1
解决办法
3311
查看次数

是否有任何部分XSD描述Delphi TClientDataSet XML文件的METADATA部分?

我知道您无法完全描述具有XSD架构的TClientDataSet的XML,因为ROW元素具有名称随内容而变化的属性.

但是,这种XML的METADATA部分应该是.

所以:有具有(部分)的XSD描述了可以用Delphi TClientDataSets被保存在XML的元数据部分的人?

问候.

PS:

感谢指向XML-> XSD转换工具/站点; 我本来应该写的,我自己也这样做了,但是以适当的方式生成XSD(即涵盖所有可能性的那个)将需要输入XML,涵盖所有可能性(如往返,rowstate等).我会尝试以这种方式提出一个像样的XSD并在此发布.

xml delphi xsd tclientdataset

9
推荐指数
2
解决办法
2375
查看次数

使用poFetchDetailsOnDemand刷新嵌套数据集

有没有办法只刷新Detail DataSet而不重新加载所有主数据集?

这是我到目前为止所尝试的:

DM.ClientDataSet2.Refresh;      
DM.ClientDataSet2.RefreshRecord;
Run Code Online (Sandbox Code Playgroud)

我也尝试过:

DM.ClientDataSet1.Refresh;
Run Code Online (Sandbox Code Playgroud)

但是上面的方法会刷新整个Master数据集,而不仅仅是当前记录.

现在,以下代码似乎做了什么:

DM.ClientDataSet1.RefreshRecord;
Run Code Online (Sandbox Code Playgroud)

是否有解决方法或正确的方法来做我想要的?(也许是插入......)

附加信息:

ClientDataSet1 =主数据集

ClientDataSet2 = Detail DataSet,如下:*

object ClientDataSet2: TClientDataSet
    Aggregates = <>
    DataSetField = ClientDataSet1ADOQuery2
    FetchOnDemand = False
    .....
end
Run Code Online (Sandbox Code Playgroud)

提供者属性:

object DataSetProvider1: TDataSetProvider
    DataSet = ADOQuery1
    Options = [poFetchDetailsOnDemand]
    UpdateMode = upWhereKeyOnly
    Left = 24
    Top = 104
  end
Run Code Online (Sandbox Code Playgroud)

delphi tclientdataset delphi-7 dataset

9
推荐指数
1
解决办法
1449
查看次数