Delphi 对象Pascal:TClientDataset删除
我正在使用TClientDataset创建内存中的数据集,以用作接收缓冲区。添加数据很好,但一旦我开始处理它,我希望能够从数据集中删除该行。调用delete works-sort of-行/索引仍然可以访问,但现在不包含有效信息 这使得事情变得有点困难,因为当我处理这个缓冲区时,实际上并不能保证条目会被删除。我不希望从第一个条目开始扫描缓冲区并跳过空项,那么有更好的方法从数据集中永久“删除”该项吗?我的想法是,它应该像实际的SQL表一样工作,删除一行不会留下空记录Delphi 对象Pascal:TClientDataset删除,delphi,tclientdataset,Delphi,Tclientdataset,我正在使用TClientDataset创建内存中的数据集,以用作接收缓冲区。添加数据很好,但一旦我开始处理它,我希望能够从数据集中删除该行。调用delete works-sort of-行/索引仍然可以访问,但现在不包含有效信息 这使得事情变得有点困难,因为当我处理这个缓冲区时,实际上并不能保证条目会被删除。我不希望从第一个条目开始扫描缓冲区并跳过空项,那么有更好的方法从数据集中永久“删除”该项吗?我的想法是,它应该像实际的SQL表一样工作,删除一行不会留下空记录 实现这一点的最佳方法是什么,或
实现这一点的最佳方法是什么,或者我使用的组件完全错误?默认情况下,客户端数据集包含更改的“日志”,因为它们还可以将客户端更改发送到远程服务器,即使这些更改是在断开连接的会话中进行的(“公文包模型”)。通常,当您将更改应用到远程数据库时,此日志会被“清除”,而任何其他更改都会与您的“本地”副本合并。
如果您不需要LogChanges并希望直接进行更改,请将其设置为False。关于代码的几点说明
MyDataSet.RecNo:= 99
while not MyDataSet.Bof do
begin
fD1 := MyDataset.FieldByName('Field1').AsInteger;
fD2 := MyDataset.FieldByName('Field2').AsInteger;
fD3 := MyDataset.FieldByName('Field3').AsInteger;
if someCondition then
MyDataset.Delete;
MyDataSet.Post;
MyDataset.Previous;
end;
你的代码有问题。我为这个案例准备了一个测试应用程序,因为几天后我将在多线程环境中面对TClientDataSet。我的测试用例应用程序没有出现这个问题(Delphi2010更新5) 我将在几天后在我自己的博客上发布这段代码。。。现在我给你的是: DFM文件:
object Form2: TForm2
Left = 0
Top = 0
Caption = 'Form2'
ClientHeight = 337
ClientWidth = 635
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnClose = FormClose
PixelsPerInch = 96
TextHeight = 13
object Memo1: TMemo
Left = 8
Top = 8
Width = 257
Height = 321
Lines.Strings = (
'Memo1')
TabOrder = 0
end
object Button1: TButton
Left = 271
Top = 8
Width = 170
Height = 25
Caption = 'Start'
TabOrder = 1
OnClick = Button1Click
end
object cdsTest: TClientDataSet
Aggregates = <>
Params = <>
Left = 584
Top = 32
object cdsTestNumber: TIntegerField
FieldName = 'Number'
end
end
object tToMemo: TTimer
Enabled = False
Interval = 500
OnTimer = tToMemoTimer
Left = 376
Top = 144
end
end
对象格式2:TForm2
左=0
Top=0
标题='Form2'
ClientHeight=337
ClientWidth=635
颜色=clBtnFace
Font.Charset=默认字符集
Font.Color=clWindowText
字体高度=-11
Font.Name='Tahoma'
Font.Style=[]
OldCreateOrder=False
OnClose=FormClose
PixelsPerInch=96
text高度=13
对象备忘录1:TMemo
左=8
Top=8
宽度=257
高度=321
行。字符串=(
"备忘录1")
TabOrder=0
结束
对象按钮1:t按钮
左=271
Top=8
宽度=170
高度=25
标题=‘开始’
TabOrder=1
OnClick=按钮1单击
结束
对象cdsTest:TClientDataSet
聚合=
参数=
左=584
Top=32
对象CDST编号:TIntegerField
字段名='Number'
结束
结束
对象:TTimer
已启用=错误
间隔=500
OnTimer=计时器
左=376
顶部=144
结束
结束
pas文件:
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DB, DBClient, SyncObjs, ExtCtrls;
type
TWriterThread = class(TThread)
private
FDataSet: TClientDataSet;
//FWriteLock: TMultiReadExclusiveWriteSynchronizer;
FLock: TCriticalSection;
public
constructor Create(ADataSet: TClientDataSet; ALock: TCriticalSection);
procedure Execute; override;
end;
TDeleterThread = class(TThread)
private
FDataSet: TClientDataSet;
//FWriteLock: TMultiReadExclusiveWriteSynchronizer;
FLock: TCriticalSection;
public
constructor Create(ADataSet: TClientDataSet; ALock: TCriticalSection);
procedure Execute; override;
end;
TForm2 = class(TForm)
cdsTest: TClientDataSet;
Memo1: TMemo;
cdsTestNumber: TIntegerField;
Button1: TButton;
tToMemo: TTimer;
procedure Button1Click(Sender: TObject);
procedure tToMemoTimer(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
FLock: TCriticalSection;
FWriterThread: TWriterThread;
FDeleterThread: TDeleterThread;
procedure cdsToMemo;
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
begin
Button1.Enabled := False;
cdsTest.CreateDataSet;
cdsTest.LogChanges := False;
FLock := TCriticalSection.Create;
tToMemo.Enabled := True;
FWriterThread := TWriterThread.Create(cdsTest, FLock);
FDeleterThread := TDeleterThread.Create(cdsTest, FLock);
end;
{ TWriterThread }
constructor TWriterThread.Create(ADataSet: TClientDataSet;
ALock: TCriticalSection);
begin
inherited Create(False);
FDataSet := ADataSet;
FLock := ALock;
end;
procedure TWriterThread.Execute;
var
I: Integer;
begin
inherited;
I := 0;
while not Terminated do
begin
FLock.Enter;
try
Inc(I);
FDataSet.AppendRecord([I]);
finally
FLock.Leave;
end;
Sleep(500); //a new record aproximately each half second
end;
end;
{ TDeleterThread }
constructor TDeleterThread.Create(ADataSet: TClientDataSet;
ALock: TCriticalSection);
begin
inherited Create(False);
FDataSet := ADataSet;
FLock := ALock;
end;
procedure TDeleterThread.Execute;
const
MaxRecords = 100;
var
ProcessedRecords: Integer;
begin
inherited;
while not Terminated do
begin
Sleep(3000); //delete records aproximately every 3 seconds
FLock.Enter;
try
FDataSet.First;
ProcessedRecords := 0;
while (not FDataSet.Eof) and (ProcessedRecords < MaxRecords) do
begin
Inc(ProcessedRecords);
if Odd(FDataSet.Fields[0].AsInteger) then
FDataSet.Delete
else
FDataSet.Next;
end;
finally
FLock.Leave;
end;
end;
end;
procedure TForm2.cdsToMemo;
begin
FLock.Enter;
try
Memo1.Lines.BeginUpdate;
try
Memo1.Lines.Clear;
cdsTest.First;
while not cdsTest.Eof do
begin
Memo1.Lines.Add(cdsTestNumber.AsString);
cdsTest.Next;
end;
finally
Memo1.Lines.EndUpdate;
end;
finally
FLock.Leave;
end;
end;
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
tToMemo.Enabled := False;
if cdsTest.Active then
begin
FDeleterThread.Terminate;
FDeleterThread.WaitFor;
FWriterThread.Terminate;
FWriterThread.WaitFor;
end;
end;
procedure TForm2.tToMemoTimer(Sender: TObject);
begin
tToMemo.Enabled := False;
cdsToMemo;
tToMemo.Enabled := True;
end;
end.
单元2;
接口
使用
窗口、消息、系统工具、变体、类、图形、控件、窗体、,
对话框、StdCtrls、DB、DBClient、SyncObjs、ExtCtrls;
类型
TWriterThread=类(TThread)
私有的
FDataSet:TClientDataSet;
//FWriteLock:TMultiReadExclusiveWriteSynchronizer;
鸥群:TCriticalSection;
公众的
构造函数创建(ADataSet:TClientDataSet;ALock:TCriticalSection);
程序执行;推翻
结束;
TDeleterThread=class(TThread)
私有的
FDataSet:TClientDataSet;
//FWriteLock:TMultiReadExclusiveWriteSynchronizer;
鸥群:TCriticalSection;
公众的
构造函数创建(ADataSet:TClientDataSet;ALock:TCriticalSection);
程序执行;推翻
结束;
TForm2=类别(TForm)
cdsTest:TClientDataSet;
备忘录1:TMemo;
CDST编号:TIntegerField;
按钮1:t按钮;
TTOMER:TTimer;
程序按钮1点击(发送方:ToObject);
程序计时器(发送方:ToObject);
过程FormClose(发送方:ToObject;var操作:TCloseAction);
私有的
{私有声明}
鸥群:TCriticalSection;
FWriterThread:TWriterThread;
FDeleterThread:TDeleterThread;
程序备忘录;
公众的
{公开声明}
结束;
变量
表2:TForm2;
实施
{$R*.dfm}
程序TForm2.按钮1单击(发件人:ToObject);
开始
按钮1.已启用:=False;
cdsTest.CreateDataSet;
cdsTest.LogChanges:=False;
FLock:=TCriticalSection.Create;
tToMemo.Enabled:=真;
FWriterThread:=TWriterThread.Create(cdsTest,FLock);
FDeleterThread:=TDeleterThread.Create(cdsTest,FLock);
结束;
{TWriterThread}
构造函数TWriterThread.Create(ADataSet:TClientDataSet;
ALock:TCriticalSection);
开始
继承创建(False);
FDataSet:=ADataSet;
羊群:=阿洛克;
结束;
过程TWriterThread.Execute;
变量
I:整数;
开始
继承;
I:=0;
虽然没有终止
开始
羊群。进入;
尝试
公司(一);
FDataSet.AppendRecord([I]);
最后
离开;
结束;
睡眠(500)//大约每半秒有一个新记录
结束;
结束;
{TDeleterThread}
构造函数TDeleterThread.Create(ADataSet:TClientDataSet;
ALock:TCriticalSection);
开始
继承创建(False);
FDataSet:=ADataSet;
羊群:=阿洛克;
结束;
过程TDeleterThread.Execute;
常数
MaxRecords=100;
变量
ProcessedRecords:整数;
开始
继承;
虽然没有终止
开始
睡眠(3000)//大约每3秒钟删除一次记录
羊群。进入;
尝试
FDataSet.First;
ProcessedRecords:=0;
而(不是FDataSet.Eof)和(ProcessedRecords