这是我的代码,用于使用触发带有参数的TFDQuery的TEdit组件搜索数据:
qryItems.ParamByName('searches').AsString := Format('%%%s%%',[edtSearch.Text]);
如果删除通配符(Format('%%% ss %%'))格式,则可以使用。通配符将帮助我过滤查询。
我喜欢代码,它简洁,直接。但是,我仍然不确定它是否正确-它没有返回任何东西!
我的问题是:上面的代码是否可用于从TEdit.OnChangeTracking事件进行查询过滤?否则,正确的做法是什么?
更新1:这是TFDQuery编辑器中的代码:
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
。
但是,鉴于您对数据集和过滤不完全熟悉,我认为您在至少两个方面使自己变得不必要地困难:
FMX + LiveBindings并非完全没有错误,并且有些怪异很可能会妨碍您。
使用LIKE运算符的语法,该语法使用井号(#
),与Format
函数中用于解析参数的哈希符号。这尤其可以是extremely令人困惑,尤其是当您尝试获得语法上有效的时像是表达式,无论是包含在查询所用的Sql中还是包含在“本地过滤器”中,即使用FDQuery的Filter
+ Filtered
属性的代码。
所以,我将提出一个建议,一开始可能不受欢迎,要做你的探索例如在VCL应用程序中进行过滤,例如以下程序。只需几分钟但与以下方法相比,可能会为您节省一些时间和神经系统的磨损试图在正在开发的FMX + LiveBinding应用程序中使其正确。方法如下:
FDConnection1: TFDConnection;
FDGUIxWaitCursor1: TFDGUIxWaitCursor;
FDQuery1: TFDQuery;
DBGrid1: TDBGrid;
DBNavigator1: TDBNavigator;
DataSource1: TDataSource;
edFilter: TEdit;
btnLocalFilter: TButton;
btnSqlFilter: TButton;
[将下面的代码添加到表单的文件中。
在行上放置调试器断点
case FilterMode of
并展示更改edFilter控件内容的应用行为然后点击两个按钮,将代码修改为适合您的数据可用。我使用的是作者的桌子,我不记得从哪里买到它但可能是来自Sql-Server的Pubs示例数据库。
[该应用程序显示-我确信您已经收集了-您可以过滤显示的数据由您的应用在服务器端通过更改用于检索数据的Sql或在客户端通过使用FDQuery的Filter
属性。为了方便您查看发生了什么,服务器端的Sql过滤是通过将edFilter.Text的内容与其余的Sql,但是在现实生活中,您应该never这样做是因为暴露于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;