如何删除 FireDAC 数据集中与某个值匹配的所有记录?
How to delete all records matching a certain value in a FireDAC dataset?
我有一个常用的 while not EOF do
循环,它从内存 table 中删除某些记录。删除最后一条记录不会按预期发出 EOF 信号。这是我的代码:
mtCt.First;
while Not mtCt.Eof do
begin
if mtCtAmt.Value = 0.0 then
mtCt.Delete
else
mtCt.Next;
end;
如何删除 FireDAC 数据集中与特定值匹配的所有记录?
您必须转到最后一个数据。
mtCt.Last;
while Not mtCt.Bof do
begin
if mtCtAmt.Value = 0.0 then
mtCt.Delete
else
mtCt.Prior;
end;
这是所有 Delphi 数据集的正常行为。
如果你的删除逻辑像你的例子一样简单,你可以忽略这个,反正下一次迭代不会满足删除条件,发出Next并进入EOF。
如果相反逻辑很复杂并且您需要避免不必要的迭代,您可以使用这样的技巧:
var
PrevRecNo: Integer;
begin
mtCt.First;
while Not mtCt.Eof do
begin
if mtCtAmt.Value = 0.0 then
begin
// save the current record number
PrevRecNo := mtCt.RecNo;
// delete will normally not change current record number
// unless you've deleted the last record, in this case
// the current record will be one less than before
mtCt.Delete;
// so, if the saved record number and the current one are
// different, you've delete the last record, just issue a
// Next in order to hit EOF and exit the while loop
if mtCt.RecNo <> PrevRecNo then
mtCt.Next;
end
else
mtCt.Next;
end;
您可以通过这种方式访问内部存储而无需导航数据集,例如:
function GetFieldIndex(Dataset: TFDDataSet; const FieldName: string): Integer;
var
I: Integer;
begin
Result := -1;
for I := 0 to Dataset.Table.Columns.Count-1 do
if Dataset.Table.Columns[I].Name = FieldName then
begin
Result := I;
Break;
end;
end;
procedure DeleteFromDataset(Dataset: TFDDataSet; const FieldName: string;
const FieldValue: Variant);
var
Col, Row: Integer;
begin
Col := GetFieldIndex(Dataset, FieldName);
if Col <> -1 then
begin
Dataset.BeginBatch;
try
{ delete all rows without navigating through dataset; this should
affect also rows that were about to be inserted but changes were
not yet applied }
for Row := Dataset.Table.Rows.Count-1 downto 0 do
if Dataset.Table.Rows[Row].GetData(Col) = FieldValue then
Dataset.Table.Rows[Row].Delete;
{ resync dataset with the just modified internal storage }
Dataset.Resync([]);
finally
Dataset.EndBatch;
end;
end;
end;
用法:
DeleteFromDataset(FDMemTable, 'MyField', 0.0);
我有一个常用的 while not EOF do
循环,它从内存 table 中删除某些记录。删除最后一条记录不会按预期发出 EOF 信号。这是我的代码:
mtCt.First;
while Not mtCt.Eof do
begin
if mtCtAmt.Value = 0.0 then
mtCt.Delete
else
mtCt.Next;
end;
如何删除 FireDAC 数据集中与特定值匹配的所有记录?
您必须转到最后一个数据。
mtCt.Last;
while Not mtCt.Bof do
begin
if mtCtAmt.Value = 0.0 then
mtCt.Delete
else
mtCt.Prior;
end;
这是所有 Delphi 数据集的正常行为。
如果你的删除逻辑像你的例子一样简单,你可以忽略这个,反正下一次迭代不会满足删除条件,发出Next并进入EOF。
如果相反逻辑很复杂并且您需要避免不必要的迭代,您可以使用这样的技巧:
var
PrevRecNo: Integer;
begin
mtCt.First;
while Not mtCt.Eof do
begin
if mtCtAmt.Value = 0.0 then
begin
// save the current record number
PrevRecNo := mtCt.RecNo;
// delete will normally not change current record number
// unless you've deleted the last record, in this case
// the current record will be one less than before
mtCt.Delete;
// so, if the saved record number and the current one are
// different, you've delete the last record, just issue a
// Next in order to hit EOF and exit the while loop
if mtCt.RecNo <> PrevRecNo then
mtCt.Next;
end
else
mtCt.Next;
end;
您可以通过这种方式访问内部存储而无需导航数据集,例如:
function GetFieldIndex(Dataset: TFDDataSet; const FieldName: string): Integer;
var
I: Integer;
begin
Result := -1;
for I := 0 to Dataset.Table.Columns.Count-1 do
if Dataset.Table.Columns[I].Name = FieldName then
begin
Result := I;
Break;
end;
end;
procedure DeleteFromDataset(Dataset: TFDDataSet; const FieldName: string;
const FieldValue: Variant);
var
Col, Row: Integer;
begin
Col := GetFieldIndex(Dataset, FieldName);
if Col <> -1 then
begin
Dataset.BeginBatch;
try
{ delete all rows without navigating through dataset; this should
affect also rows that were about to be inserted but changes were
not yet applied }
for Row := Dataset.Table.Rows.Count-1 downto 0 do
if Dataset.Table.Rows[Row].GetData(Col) = FieldValue then
Dataset.Table.Rows[Row].Delete;
{ resync dataset with the just modified internal storage }
Dataset.Resync([]);
finally
Dataset.EndBatch;
end;
end;
end;
用法:
DeleteFromDataset(FDMemTable, 'MyField', 0.0);