DELPHI TFDQuery碎片总结
一.过虑器:FILTER
1.属性设置

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.在编辑器中,连接符用 & 而不是 + ,常量字符串用单引号括起来.

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语句一起处理.比如:

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

以下是官方的说明:
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.快速决策表

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之后.当要查找的字段是文本时,第三参数才有意义.第三参数含义如下:

// 删除操作 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;

浙公网安备 33010602011771号