【问题标题】:How to mark all TClientDataSet records as Inserted?如何将所有 TClientDataSet 记录标记为已插入?
【发布时间】:2010-02-05 20:00:48
【问题描述】:

我有一个复杂的事务,它将来自多个 TClientDataSet 的数据保存在数据库中。

其中一个 ClientDataSet 总是将数据附加到底层表,例如。生成 INSERT 语句,无论现有记录来自何处。

我现在强制插入:

// Create temp table, assign all target data, 
// Empty target table, append data from temp

Tmp := TClientDataSet.Create; 
Tmp.Data := Table.Data; 

Table.MergeChangeLog; 
Table.EmptyDataSet;

Tmp.First; 
// Append all records 
While not Tmp.Eof do
begin
  Table.Append;  
  for i := 0 to Table.FieldCount - 1 do
    Table.Fields[i].Value := Tmp.Fields[i].Value 
  Table.Post; 

  Tmp.Next;
end;

Tmp.Free;

有没有更简单的方法将所有记录标记为已插入?

【问题讨论】:

  • 您的解决方案似乎很简单。我最终会为 Tmp.Free 添加一个尝试,但仅此而已。

标签: delphi dbexpress


【解决方案1】:

希望某事。这样会起作用(至少在没有计算字段时);

uses
  dsintf;

[..]
procedure TForm1.Button1Click(Sender: TObject);
begin
  ClientDataSet1.First;
  while not ClientDataSet1.Eof do begin
    PRecInfo(ClientDataSet1.ActiveBuffer +
        ClientDataSet1.RecordSize).Attribute := dsRecNew;
    ClientDataSet1.Next;
  end;
end;

好吧,它可以工作,但只要没有重新检索数据。即TCustomClientDataSet.GetRecord 重新设置记录属性。我猜这使得 hacky 方法毫无用处。

也许可以尝试绑定一个数据感知控件,看看设置 DataSource 的 DataLink 的 BufferCount 是否会有所帮助。或者,尝试在后代 ClientDataSet 中覆盖 GetRecord。但我怀疑这是否值得。

[编辑]

记录属性可以在“AfterScroll”事件中破解。例如,这将有助于代码测试 UpdateStatus 以返回“usInserted”。

procedure TForm1.ClientDataSet1AfterScroll(DataSet: TDataSet);
begin
  PRecInfo(DataSet.ActiveBuffer + DataSet.RecordSize).Attribute := dsRecNew;
end;

测试是否插入了所有记录

procedure TForm1.Button1Click(Sender: TObject);
begin
  ClientDataSet1.First;
  while not ClientDataSet1.Eof do begin
    if not (ClientDataSet1.UpdateStatus = usInserted) then
      raise Exception.Create('The record is not inserted');
    ClientDataSet1.Next;
  end;
end;



可以派生一个新的 TClientDataSet 来检索始终“插入”的记录。

(类型声明位于 包含 ClientDataSet 的表单/数据模块之前)

type
  TClientDataset = class(dbclient.TClientDataSet)
    function GetRecord(Buffer: PChar; GetMode: TGetMode; DoCheck: Boolean):
        TGetResult; override;
  end;
[..]
implementation

function TClientDataset.GetRecord(Buffer: PChar; GetMode: TGetMode;
  DoCheck: Boolean): TGetResult;
begin
  Result := inherited GetRecord(Buffer, GetMode, DoCheck);
  if Result = grOk then
    PRecInfo(Buffer + RecordSize).Attribute := dsRecNew;
end;

现在对于所有记录,UpdateStatus 将返回“usInserted”。

编辑

我终于明白,目的是为所有记录生成插入 SQL。我们不会通过修改 DataSet 的记录属性来实现这一点,ApplyUpdates 只考虑“Delta”,我们可能没有 Delta。可能有不同的方法来实现这一点,下面的示例假设 DataSet 有一个 Provider 并且我们能够在其上放置一个事件处理程序。

type
  TForm1 = class(TForm)
    [..]
  private
    procedure DeltaAfterScroll(DataSet: TDataSet);
    [..]

implementation

procedure TForm1.DeltaAfterScroll(DataSet: TDataSet);
begin
// The UpdateTree of the Resolver of the Provider will visit each 
// record to get the UpdateStatus
  PRecInfo(DataSet.ActiveBuffer + DataSet.RecordSize).Attribute := dsRecNew;
end;


type
  TAccessCCDS = class(TCustomClientDataSet);

procedure TForm1.Button1Click(Sender: TObject);
var
  Count: Integer;
begin
  ClientDataSet1.MergeChangeLog;
// Since there's no "Delta", ApplyUpdates will return immediately.
// Hence, we'll force an update by calling DoApplyUpdates, bypassing the
// ChangeCount test, and update with the "Data".
// Reconcilation is left out for simplicity.
  TAccessCCDS(ClientDataSet1).DoApplyUpdates(ClientDataSet1.Data, 0, Count);
end;

procedure TForm1.DataSetProvider1UpdateData(Sender: TObject;
  DataSet: TCustomClientDataSet);
begin
// Will be called once when ApplyUpdates is called.
  TAccessCCDS(DataSet).AfterScroll := DeltaAfterScroll;
end;

【讨论】:

  • 正如我在答案中所说,如果您离开被黑的记录并且 BufferCount 为 1,这将不起作用。因为我不知道您在使用“usInserted”记录做什么很难猜测 - 欺骗代码以相信记录被插入而它们没有被插入 - 是否会达到您的目的。无论如何我都会编辑答案...
  • 将所有记录设置为插入后,我执行 ApplyUpdates(0)。事实上,我想要的只是为 ClientDataSet 中的每一行生成“INSERT INTO TABLE ...”。
  • 既然没有简单的答案,而且您提出了一些不错的想法,我会接受您的回答。我希望 Embarcadero 正在阅读这篇文章,我留下来。
  • 将记录标记为已插入将无济于事。 ApplyUpdates 应用“Delta”而不是“Data”。可能我们这里没有增量,否则你不会尝试这个。我再编辑一次。我的,这将是一个很长的答案。
猜你喜欢
  • 1970-01-01
  • 2011-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-04
  • 1970-01-01
相关资源
最近更新 更多