DELPHI TFDQuery碎片总结

一.过虑器:FILTER 

1.属性设置

image

 

Filter: 过虑器

Filtered: 过虑器开关. 只有开关打开时,过虑器才会工作.

FilterOptions - foCaseInsensitive : 不区分大小写,也可以在代码中使用UpperCase对条件进行统一大写

FilterOptions - foNoPartialCompare: 不进行局部比较.字面意思.

 

2.支持的操作符.

[ ]  :把字段名括起来

+ : 连接符.用于连接字段,比如图中的 [客户名称] + [助记码],但是要注意,如果两个字段的类型不致,会报错,比如 [客户ID] + [客户名称] 这样就不行

% :用于模糊匹配.注意我这里用的是ACCESS数据库,其他数据库用的可能是*号,请自行尝试

关于日期

FlieterStr:='[创建日期]=#2026-02-27#';    //错误
FlieterStr:='[创建日期]=''2026-02-27''';    //正确

 2026-5-27 补充

 DM.FDQuery1.Filter := '(助记码 + 物料代码 + 物料名称 + 规格型号 +  IIF(备注 IS NULL, '''', 备注)) LIKE ' + str;

如果[备注]字段存在null值时,需要使用IIF转换为 '' 空字符串,注,不能使用NZ (ACCESS)

 

二.SQL语句

1.在编辑器中,连接符用 & 而不是 + ,常量字符串用单引号括起来.

image

 2.尽量不要用数据库特有的方法,因为SQL语句首先得通过TFDQuery组件的确认.而有些数据库特有的方法是与之不相兼容的.比如ACCESS中的NZ

3.如果是在代码中动态设置SQL语句,你得像下面这么写

FDQuery1.SQL.Text := 'select 仓库ID  & ''' +'A'+'''  from 仓库列表';

最最核心的技巧是拼字符串.我们知道,字符串要用单引号括起来,比如

仓库ID  &  'A'    

但是在代码里,你不能这么写,因为在代码里,字符串默认是带了一对单引号的,你如果还想额外加入单引号这个字符串,记住这句话: 一个变俩儿! 比如:

仓库ID  &  '''A'''

上面的'''A''',编辑成SQL语句就会变成了'A'(带了一对单引).但是这里还有个问题.你直接写成下面的形式,它又不对了:

FDQuery1.SQL.Text := 'select 仓库ID  & '''A'''  from 仓库列表';

因为sql语句前后都带了个单引号,使得A没有被连接起来,IDE直接就会给你报错了.

如果你在代码中拼接SQL语句需要使用模糊匹配,请使用 % 符号,而不是 * (ACCESS)

最后就是关于&和+了,SQL语句内部连接字符串请用&,IDE里面连接字符串,请用+.

注意各种数据库之间,连接字符串的运行符不一定是 &,请按实际情况选择

 

2026-04-14 补充

三.批量处理数据集

TFDQuery支持命令批处理.也就是支持多条SQL语句一起处理.比如:

image

 我以前一直不知道 [下一个记录集]这个按钮是做什么的,现在总算明白了.但是很遗憾,这个功能并不支持ACCESS

image

 以下是官方的说明:

Command Batches (FireDAC) - RAD Studio (embarcadero.com)

 2026-05-08 更新

1.设计面板上的每一个FDQuery都应该拥有自己特定的功能,不要混用,不要混用,不要混用

2.对于经常需要进行临时查询的项目,建议封装一个通用函数.比如

function TempFDQuery(var isql: string): TFDQuery;
begin  //封装
    var FQ := TFDQuery.Create(nil);
    FQ.Connection := Dm.FDConnection1;
    FQ.SQL.Text := isql;
    FQ.Open();
    Result := FQ;
end;

procedure QueryData();   //调用
begin
    var isql := 'select * from table1';
    var FQ := TempFDQuery(isql);
    var n := FQ.FieldByName('QY').AsInteger;
    FQ.Free;
end;

 2026-5-14 补充

五.书签技巧

我们在对数据集进行增删改查后,通常都要刷新一下数据集,但是刷新过后,数据集的指针会重新返回到第一的位置.我希望在刷新后,让指针回到原来的位置怎么办?

使用BookMark书签功能,能让你快速实现功能.它是一个指向数据集中特定记录的临时指针(内存地址引用),类型为 TBookmark(本质是 Pointer)

1.快速决策表

image

 2.常用的方法有:

Bookmark:保存或者恢复书签,适用于EDIT

var mark := FDQuery1.Bookmark; //保存当前书签
//....
  FDQuery1.Bookmark := mark;//恢复书签

 

RefreshRecord:仅刷新当前正在修改的记录

FDQuery1.Edit;
//....
FDQuery1.Post;
FDQuery1.RefreshRecord;
//Refresh:刷新所有记录,但是Bookmark功能会失效
//RefreshRecord:仅刷新修改的记录的数据,Bookmark功能正常

 如果你有使用cxgrid来显示数据,那么这里还会有个问题.

TcxGrid 与 TDataSet 之间有一层 DataController,它负责管理数据的缓存和显示。当你调用 FDQuery1.RefreshRecord 时,数据集(FDQuery1)中的字段值确实被更新了.但 cxGrid 的 DataController 不知道数据已经变化,它仍在使用旧的缓存数据显示在界面上,所以你会看到 cxGrid 内容没有发会变化,解决的方案是:

FDQuery1.RefreshRecord;
//告诉 cxGrid 外部数据已改变,需要刷新显示
GridView2.DataController.RefreshExternalData;

那为什么为直接使用GridView2.DataController.RefreshExternalData呢?因为它只能向FDQuery1拿数据而不能向服务器直接拿.RefreshRecord 的作用就是是向数据拿数据给FDQuery1

 

BookmarkValid:判断书签是否仍然有效.

if FDQuery1.BookmarkValid(mark) then
      FDQuery1.Bookmark := mark;

 

Locate:按主键恢复书签,适用于DELETE,Refresh之后.当要查找的字段是文本时,第三参数才有意义.第三参数含义如下:

image

 

// 删除操作
var ID := FDQuery1.FieldByName('ID').AsInteger;
FDQuery1.Delete;
FDQuery1.Locate('ID', ID, []);

 

GotoBookmark:直接跳到指定书签.

if not FDQuery1.GotoBookmark(mark) then
  FDQuery1.First;  // 失败时的备选方案

FreeBookmark:释放书签内存.虽然程序会自动释放书签,但最好能用try...finally语句显式释放,避免出错时书签得不到正常释放

var
  mark: TBookmark;
begin
  mark := FDQuery1.Bookmark;
  try
    // 使用 mark...
  finally
    FDQuery1.FreeBookmark(mark);
  end;
end;

 

posted @ 2026-03-27 10:09  一曲轻扬  阅读(34)  评论(0)    收藏  举报