FireDAC Delphi中TEdit搜索函数的通配符格式是什么

FireDAC Delphi中TEdit搜索函数的通配符格式是什么,delphi,firedac,Delphi,Firedac,这是我使用TEdit组件搜索数据的代码,该组件使用参数触发TFDQuery: qryItems.ParamByName('searches').AsString := Format('%%%s%%',[edtSearch.Text]); 如果我删除了通配符(格式('%%%s%%')格式,它就会工作。通配符将帮助我筛选查询 我喜欢代码,它干净、简单、直截了当。但是,我仍然不确定它是否正确——它没有返回任何东西 我的问题是: 上面的代码是否用于从TEdit.OnChangeTracking事件进行

这是我使用TEdit组件搜索数据的代码,该组件使用参数触发TFDQuery:

qryItems.ParamByName('searches').AsString := Format('%%%s%%',[edtSearch.Text]);
如果我删除了通配符(格式('%%%s%%')格式,它就会工作。通配符将帮助我筛选查询

我喜欢代码,它干净、简单、直截了当。但是,我仍然不确定它是否正确——它没有返回任何东西

我的问题是: 上面的代码是否用于从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]);

我认为这里的罪魁祸首是这种代码格式(“%%s%%”,[edtSearch.Text]),我没有弄清楚这一点。

一个简短的答案是,您希望以这样的参数赋值结束:

  FDQuery1.Params[0].AsString := '%a%';
  FDQuery1.Open();
  FDQuery1.Params[0].AsString := Format('%%%s%%', [edFilter.Text]);
假设希望在类似表达式中匹配的值只是字母
a
。或者,如果要使用
格式
,可以执行以下操作:

  FDQuery1.Params[0].AsString := '%a%';
  FDQuery1.Open();
  FDQuery1.Params[0].AsString := Format('%%%s%%', [edFilter.Text]);
在一行中使用三个哈希符号的原因是,第一个符号“转义”表达式格式中的第二个符号求值,第三个符号在“s”与它组合以作为字符串的占位符(格式构造其结果时)

但是,鉴于您对使用数据集和过滤并不完全熟悉, 我认为你至少在两个方面给自己造成了不必要的困难:

  • FMX+LiveBindings并非完全没有bug,并且有一些可能会妨碍您的怪癖

  • 使用LIKE运算符(使用哈希符号(
    #
    )的语法与用法冲突 用于解析
    格式
    函数中的参数的哈希符号。这一点尤其重要 非常令人困惑,尤其是当您试图获取语法上有效的 与表达式类似,无论是要包含在查询使用的Sql中,还是要包含在“本地筛选器”中, i、 e.使用FDQuery的
    过滤器
    +
    过滤的
    属性的一种

因此,我将提出一个最初可能不受欢迎的建议, 那就是做你的探索 在VCL应用程序中进行过滤之类的操作,如下面的应用程序。设置只需几分钟, 但与之相比,这可能会为你节省一些时间和神经系统的磨损 试图在正在开发的FMX+LiveBinding应用程序中正确使用它。以下是如何:

  • 创建一个新的VCL应用程序并将这些组件添加到其中
  • 将下面的代码添加到表单的文件中

  • 在该行上放置调试器断点

  • 并了解应用程序更改edFilter控件内容的行为 一旦你将代码改编成你所拥有的数据,点击这两个按钮 可获得的我用的是作者的表格,我不记得是从哪里弄来的 但它可能来自于Sql Server的Pubs示例数据库

    这个应用程序显示——我相信你已经收集到了——你可以过滤显示的数据 您的应用程序可以在服务器端更改用于检索数据的Sql,也可以在客户端使用 FDQuery的
    过滤器
    属性。这样您就可以很容易地看到发生了什么,服务器端的Sql 过滤是通过将edFilter.Text的内容与 Sql的其余部分,但在现实生活中,您不应该因为 它的风险敞口

    代码


    我需要通配符,以免GUI上的数据过载,这毫无意义。添加通配符会增加返回的数据量。是否有些验证也不清楚-您做了哪些验证?如果代码不能按您需要的方式工作,那么您是否喜欢该代码是无关紧要的,但是您没有解释任何问题。请把你的问题说清楚。@KenWhite请容忍我在这里的措辞。重载数据的意思是-我只想在TListView中加载我需要的数据。验证是关于我所做的进一步研究,但我发现的并不多。我已经重新措辞了这个问题,希望这次更清楚。你的问题很难理解。如果是“如何在SQL中使用通配符”,答案是“通过使用
    LIKE
    操作符”。我在@Olivier上面添加了一些更新,特别是SQL部分。它从您的第一个建议就可以正常工作!FDQuery1.Params[0]。关联字符串:=“%a%”;。剩下的我将不得不探索。它看起来很优雅干净。值得探索。非常感谢你!
    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;