FireDAC 中 TEdit 搜索功能的通配符格式是什么 Delphi
What is the wildcards format for TEdit search function in FireDAC Delphi
这是我使用 TEdit 组件搜索数据的代码,该组件使用参数触发 TFDQuery:
qryItems.ParamByName('searches').AsString := Format('%%%s%%',[edtSearch.Text]);
如果我删除通配符 (Format('%%%s%%')) 格式,它会起作用。通配符将帮助我过滤查询。
我喜欢代码,它干净、简单、直接。但是,我仍然不确定它是否正确——它没有返回任何东西!
我的问题是:
上面的代码是否适用于 TEdit.OnChangeTracking 事件的查询过滤?否则,正确的做法是什么?
更新 1:
这是来自 TFDQuery Editor 的代码:
SELECT category.name AS category, item.name, item.description
FROM item
JOIN category ON item.category_id = category.list_id
WHERE item.description LIKE :searches
ORDER BY item.sellable
LIMIT 100
现在,我试图在运行时从这段代码访问它,但它不起作用:
qryItems.ParamByName('searches').AsString := Format('%%%s%%',[edtSearch.Text]);
我认为这里的罪魁祸首是这段代码 Format('%%%s%%',[edtSearch.Text]),我没听对。
一个简短的回答是您希望以这样的参数分配结束:
FDQuery1.Params[0].AsString := '%a%';
FDQuery1.Open();
假设您要在 LIKE 表达式中匹配的值只是字母 a
。或者,如果你想使用 Format
,你可以这样做:
FDQuery1.Params[0].AsString := Format('%%%s%%', [edFilter.Text]);
连续出现三个哈希符号的原因是表达式 Format 中的第一个 'escapes' 和第二个计算,第三个紧接在 's' 之前与它作为 Format 构造其结果的字符串的占位符。
但是,鉴于您对使用数据集和过滤并不完全熟悉,
我认为你至少在两个方面给自己造成了不必要的困难:
FMX + LiveBindings 并非完全没有错误,并且有一些怪癖可能会妨碍您。
使用 LIKE 运算符的语法使用井号 (#
),与使用冲突
用于解析 Format
函数中的参数的哈希符号。这尤其可以是
极度令人困惑,尤其是当您试图获得语法上有效的
LIKE 表达式,无论是包含在您的查询使用的 Sql 中还是包含在“本地过滤器”中,
即使用 FDQuery 的 Filter
+ Filtered
属性的一个。
所以,我要提出一个最初可能不受欢迎的建议,
这是做你的探索
在 VCL 应用程序中进行过滤之类的事情,例如下面的应用程序。设置只需几分钟,
但与
试图在正在开发的 FMX + LiveBinding 应用程序中正确使用它。方法如下:
- 创建一个新的 VCL 应用程序并将这些组件添加到其中。
FDConnection1: TFDConnection;
FDGUIxWaitCursor1: TFDGUIxWaitCursor;
FDQuery1: TFDQuery;
DBGrid1: TDBGrid;
DBNavigator1: TDBNavigator;
DataSource1: TDataSource;
edFilter: TEdit;
btnLocalFilter: TButton;
btnSqlFilter: TButton;
将下面的代码添加到表单的文件中。
在行上放置一个调试器断点
case FilterMode of
并探索应用更改 edFilter 控件内容的行为
然后单击两个按钮,一旦您将代码调整为您拥有的数据
可用的。我的使用作者的 table,我不记得从哪里得到的
但也许它来自 Sql-Server.
的 Pubs 示例数据库
该应用程序显示 - 正如我确定您已经收集到的那样 - 您可以过滤显示的数据
通过您的应用程序在服务器端通过更改 Sql 用于检索数据或在客户端通过使用
FDQuery 的 Filter
属性。这样你就可以很容易地看到发生了什么,服务器端的 Sql
过滤是通过将 edFilter.Text 的内容与
Sql 的其余部分,但在现实生活中,你应该 永远不要 这样做,因为
它暴露于 Sql Injection exploit.
代码
type
TFilterMode = (fmLocal, fmSql);
type
TForm1 = class(TForm)
[...]
public
{ Public declarations }
FilterMode : TFilterMode;
end;
[...]
const
sOrderBy = ' order by lastname, forename';
sSql = 'select * from authors';
sFilteredSql = sSql + ' where lastname like :lastname%';
sLocalFilter = 'lastname like ''%%s%%''';
procedure TForm1.OpenFDQuery;
var
S : String;
begin
if FDQuery1.Active then FDQuery1.Close;
FDQuery1.Params.Clear;
FDQuery1.Filter := '';
FDQuery1.Filtered := True;
case FilterMode of
fmSql : begin
FDQuery1.Sql.Text := '';
// WARNING - don't do this for real - risk of Sql Injection exploit
// use a parameterised query instead - see http://docwiki.embarcadero.com/RADStudio/Rio/en/Using_Parameters_in_Queries
S := 'select * from authors where lastname like ''%' + edFilter.Text + '%''';
FDQuery1.Sql.Text := S;
end;
fmLocal : begin
FDQuery1.Sql.Text := sSql + sOrderBy;
S := 'lastname like ''%' + edFilter.Text + '%''';
FDQuery1.Filter := S;
FDQuery1.Filtered := True;
end;
end;
FDQuery1.Open;
end;
procedure TForm1.ApplySqlFilter;
begin
FilterMode := fmLocal;
OpenFDQuery;
end;
procedure TForm1.ApplyLocalFilter;
begin
FilterMode := fmLocal;
OpenFDQuery;
end;
procedure TForm1.btnLocalFilterClick(Sender: TObject);
begin
ApplyLocalFilter;
end;
procedure TForm1.btnSqlFilterClick(Sender: TObject);
begin
ApplySqlFilter;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
edFilter.Text := 'a';
end;
这是我使用 TEdit 组件搜索数据的代码,该组件使用参数触发 TFDQuery:
qryItems.ParamByName('searches').AsString := Format('%%%s%%',[edtSearch.Text]);
如果我删除通配符 (Format('%%%s%%')) 格式,它会起作用。通配符将帮助我过滤查询。
我喜欢代码,它干净、简单、直接。但是,我仍然不确定它是否正确——它没有返回任何东西!
我的问题是: 上面的代码是否适用于 TEdit.OnChangeTracking 事件的查询过滤?否则,正确的做法是什么?
更新 1: 这是来自 TFDQuery Editor 的代码:
SELECT category.name AS category, item.name, item.description
FROM item
JOIN category ON item.category_id = category.list_id
WHERE item.description LIKE :searches
ORDER BY item.sellable
LIMIT 100
现在,我试图在运行时从这段代码访问它,但它不起作用:
qryItems.ParamByName('searches').AsString := Format('%%%s%%',[edtSearch.Text]);
我认为这里的罪魁祸首是这段代码 Format('%%%s%%',[edtSearch.Text]),我没听对。
一个简短的回答是您希望以这样的参数分配结束:
FDQuery1.Params[0].AsString := '%a%';
FDQuery1.Open();
假设您要在 LIKE 表达式中匹配的值只是字母 a
。或者,如果你想使用 Format
,你可以这样做:
FDQuery1.Params[0].AsString := Format('%%%s%%', [edFilter.Text]);
连续出现三个哈希符号的原因是表达式 Format 中的第一个 'escapes' 和第二个计算,第三个紧接在 's' 之前与它作为 Format 构造其结果的字符串的占位符。
但是,鉴于您对使用数据集和过滤并不完全熟悉, 我认为你至少在两个方面给自己造成了不必要的困难:
FMX + LiveBindings 并非完全没有错误,并且有一些怪癖可能会妨碍您。
使用 LIKE 运算符的语法使用井号 (
#
),与使用冲突 用于解析Format
函数中的参数的哈希符号。这尤其可以是 极度令人困惑,尤其是当您试图获得语法上有效的 LIKE 表达式,无论是包含在您的查询使用的 Sql 中还是包含在“本地过滤器”中, 即使用 FDQuery 的Filter
+Filtered
属性的一个。
所以,我要提出一个最初可能不受欢迎的建议, 这是做你的探索 在 VCL 应用程序中进行过滤之类的事情,例如下面的应用程序。设置只需几分钟, 但与 试图在正在开发的 FMX + LiveBinding 应用程序中正确使用它。方法如下:
- 创建一个新的 VCL 应用程序并将这些组件添加到其中。
FDConnection1: TFDConnection;
FDGUIxWaitCursor1: TFDGUIxWaitCursor;
FDQuery1: TFDQuery;
DBGrid1: TDBGrid;
DBNavigator1: TDBNavigator;
DataSource1: TDataSource;
edFilter: TEdit;
btnLocalFilter: TButton;
btnSqlFilter: TButton;
将下面的代码添加到表单的文件中。
在行上放置一个调试器断点
case FilterMode of
并探索应用更改 edFilter 控件内容的行为 然后单击两个按钮,一旦您将代码调整为您拥有的数据 可用的。我的使用作者的 table,我不记得从哪里得到的 但也许它来自 Sql-Server.
的 Pubs 示例数据库该应用程序显示 - 正如我确定您已经收集到的那样 - 您可以过滤显示的数据
通过您的应用程序在服务器端通过更改 Sql 用于检索数据或在客户端通过使用
FDQuery 的 Filter
属性。这样你就可以很容易地看到发生了什么,服务器端的 Sql
过滤是通过将 edFilter.Text 的内容与
Sql 的其余部分,但在现实生活中,你应该 永远不要 这样做,因为
它暴露于 Sql Injection exploit.
代码
type
TFilterMode = (fmLocal, fmSql);
type
TForm1 = class(TForm)
[...]
public
{ Public declarations }
FilterMode : TFilterMode;
end;
[...]
const
sOrderBy = ' order by lastname, forename';
sSql = 'select * from authors';
sFilteredSql = sSql + ' where lastname like :lastname%';
sLocalFilter = 'lastname like ''%%s%%''';
procedure TForm1.OpenFDQuery;
var
S : String;
begin
if FDQuery1.Active then FDQuery1.Close;
FDQuery1.Params.Clear;
FDQuery1.Filter := '';
FDQuery1.Filtered := True;
case FilterMode of
fmSql : begin
FDQuery1.Sql.Text := '';
// WARNING - don't do this for real - risk of Sql Injection exploit
// use a parameterised query instead - see http://docwiki.embarcadero.com/RADStudio/Rio/en/Using_Parameters_in_Queries
S := 'select * from authors where lastname like ''%' + edFilter.Text + '%''';
FDQuery1.Sql.Text := S;
end;
fmLocal : begin
FDQuery1.Sql.Text := sSql + sOrderBy;
S := 'lastname like ''%' + edFilter.Text + '%''';
FDQuery1.Filter := S;
FDQuery1.Filtered := True;
end;
end;
FDQuery1.Open;
end;
procedure TForm1.ApplySqlFilter;
begin
FilterMode := fmLocal;
OpenFDQuery;
end;
procedure TForm1.ApplyLocalFilter;
begin
FilterMode := fmLocal;
OpenFDQuery;
end;
procedure TForm1.btnLocalFilterClick(Sender: TObject);
begin
ApplyLocalFilter;
end;
procedure TForm1.btnSqlFilterClick(Sender: TObject);
begin
ApplySqlFilter;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
edFilter.Text := 'a';
end;