Delphi XE5获取 TClientDataSet 的变更明细
在 Delphi XE5 中,要获取 TClientDataSet 的变更明细(包括新增、修改、删除的记录),可以通过其内置的 Delta 属性 和 状态标志 实现。以下是详细步骤和代码示例:
核心方法:使用 Delta 属性
TClientDataSet 内部维护了一个变更日志(Delta),记录所有未提交的更改。通过访问 Delta 属性,可获取完整的变更明细。
步骤 1:获取变更数据集
var
DeltaCDS: TClientDataSet;
begin
// 创建临时数据集接收变更信息
DeltaCDS := TClientDataSet.Create(nil);
try
// 将源 ClientDataSet 的变更数据赋给 DeltaCDS
DeltaCDS.Data := cdsMain.Delta; // cdsMain 是你的主数据集
if DeltaCDS.IsEmpty then
ShowMessage('没有变更记录')
else
// 遍历变更记录(见下一步骤)
...
finally
DeltaCDS.Free;
end;
end;
步骤 2:遍历变更记录并识别状态
每条变更记录都有一个 UpdateStatus 属性,标识其状态(新增、修改、删除)。遍历 DeltaCDS 即可获取明细:
DeltaCDS.First;
while not DeltaCDS.Eof do
begin
case DeltaCDS.UpdateStatus of
usInserted: // 新增记录
begin
ShowMessage('新增: ID=' + DeltaCDS.FieldByName('ID').AsString);
end;
usModified: // 修改记录
begin
// 获取修改前和修改后的值
Field := DeltaCDS.FieldByName('Price');
ShowMessage(Format('修改: ID=%s, Price (旧值=%.2f, 新值=%.2f)', [
DeltaCDS.FieldByName('ID').AsString,
Field.OldValue, // 修改前的值
Field.NewValue // 修改后的值
]));
end;
usDeleted: // 删除记录
begin
ShowMessage('删除: ID=' + DeltaCDS.FieldByName('ID').AsString);
end;
end;
DeltaCDS.Next;
end;
关键属性说明
| 属性/方法 | 作用 |
|---|---|
Delta |
返回包含所有变更的 OleVariant,可赋值给另一个 TClientDataSet |
UpdateStatus |
记录状态:usInserted(新增)、usModified(修改)、usDeleted(删除) |
Field.OldValue |
获取字段修改前的值(仅 usModified 状态有效) |
Field.NewValue |
获取字段修改后的值 |
ChangeCount |
返回变更记录的总数量(整数) |
完整代码示例
procedure TForm1.GetChangeDetails;
var
DeltaCDS: TClientDataSet;
Field: TField;
Detail: string;
begin
if cdsMain.ChangeCount = 0 then
begin
ShowMessage('没有变更记录');
Exit;
end;
DeltaCDS := TClientDataSet.Create(nil);
try
DeltaCDS.Data := cdsMain.Delta; // 加载变更数据
DeltaCDS.First;
Memo1.Lines.Clear; // 用 TMemo 显示明细
Memo1.Lines.Add('===== 变更明细 =====');
while not DeltaCDS.Eof do
begin
Detail := '';
case DeltaCDS.UpdateStatus of
usInserted:
Detail := Format('新增: ID=%s, Name=%s', [
DeltaCDS.FieldByName('ID').AsString,
DeltaCDS.FieldByName('Name').AsString
]);
usModified:
begin
Field := DeltaCDS.FieldByName('Price');
Detail := Format('修改: ID=%s, Price 旧值=%.2f → 新值=%.2f', [
DeltaCDS.FieldByName('ID').AsString,
Field.OldValue,
Field.NewValue
]);
end;
usDeleted:
Detail := Format('删除: ID=%s', [
DeltaCDS.FieldByName('ID').AsString
]);
end;
if Detail <> '' then
Memo1.Lines.Add(Detail);
DeltaCDS.Next;
end;
finally
DeltaCDS.Free;
end;
end;
注意事项
-
Delta 数据集为只读:
通过Delta获取的数据集只能遍历,不能直接修改(会引发异常)。 -
清除变更记录:
调用MergeChangeLog或ApplyUpdates后,变更明细会被清空。如需保留变更,应在操作前获取 Delta。 -
字段内容不一致:
- 新增记录(
usInserted):所有字段均为新值。 - 修改记录(
usModified):通过OldValue和NewValue对比变化。 - 删除记录(
usDeleted):记录存在但字段值为空,需通过标识确认。
- 新增记录(
-
性能优化:
对大型数据集,在遍历前调用DisableControls提高性能,遍历结束后调用EnableControls。
替代方案:直接遍历主数据集
如果不想使用 Delta,可通过遍历主数据集并检查状态获取变更(效率较低):
cdsMain.First;
while not cdsMain.Eof do
begin
case cdsMain.UpdateStatus of
usModified:
begin
// 直接访问字段的 OldValue/NewValue
ShowMessage('修改: ' + cdsMain.FieldByName('Name').OldValue);
end;
// ...其他状态处理
end;
cdsMain.Next;
end;
通过上述方法,你可以在 Delphi XE5 中完整追踪 TClientDataSet 的所有变更明细。

浙公网安备 33010602011771号