Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi中DBGrid的SQL过滤_Sql_Delphi_Filtering_Firebird_Dbgrid - Fatal编程技术网

Delphi中DBGrid的SQL过滤

Delphi中DBGrid的SQL过滤,sql,delphi,filtering,firebird,dbgrid,Sql,Delphi,Filtering,Firebird,Dbgrid,我想要一个DBGrid,显示根据4个dbLookupCombobox过滤的产品 如果我选择了一个制造商,类别1-3将更新/过滤,并仅显示所选制造商产品的现有类别。 如果然后选择类别1,则类别2-3将更新/筛选,并仅显示所选制造商和类别1的现有产品类别。 与类别1相同,但包括类别1的选择 此外,我希望能够只从类别1+2中选择,而不选择制造商 无论我从这4个组合中选择什么,我都希望DBGrid更新并显示过滤后的产品 过滤完成后,我想要一个重置过滤器按钮重新开始 情景: 1x FDConnection

我想要一个DBGrid,显示根据4个dbLookupCombobox过滤的产品
如果我选择了一个制造商,类别1-3将更新/过滤,并仅显示所选制造商产品的现有类别。
如果然后选择类别1,则类别2-3将更新/筛选,并仅显示所选制造商和类别1的现有产品类别。
与类别1相同,但包括类别1的选择

此外,我希望能够只从类别1+2中选择,而不选择制造商

无论我从这4个组合中选择什么,我都希望DBGrid更新并显示过滤后的产品

过滤完成后,我想要一个重置过滤器按钮重新开始

情景:

1x FDConnection, Firebird.
5x FDQuery and Datasources
1x DBGrid
4x dbLookupComboBox
1x Button
查询:

FDQuery1: FDQ_Manufacturers:
  select distinct MANUFACTURERNAME from Products where
  upper (CATEGORYTEXT1) like upper(:CATEGORYTEXT1)
  and upper(CATEGORYTEXT2) like upper(:CATEGORYTEXT2)
  and upper(CATEGORYTEXT3) like upper(:CATEGORYTEXT3)

FDQuery2: FDQ_Category1
  select distinct CATEGORYTEXT1 from Products where
  upper(MANUFACTURERNAME) like upper(:MANUFACTURERNAME)

FDQuery3: FDQ_Category2
  select distinct CATEGORYTEXT2 from Products where 
  upper(MANUFACTURERNAME) like upper(:MANUFACTURERNAME)
  and upper(CATEGORYTEXT1) like upper(:CATEGORYTEXT1)

FDQuery4: FDQ_Category3
  select distinct CATEGORYTEXT3 from Products where
  upper(MANUFACTURERNAME) like upper(:MANUFACTURERNAME)
  and upper(CATEGORYTEXT1) like upper(:CATEGORYTEXT1)
  and upper(CATEGORYTEXT2) like upper(:CATEGORYTEXT2)

FDQuery5: FDQ_Products
  select first 100 * from Products where  
  and upper(MANUFACTURERNAME) like upper(:MANUFACTURERNAME) 
  and upper(CATEGORYTEXT1) like upper(:CATEGORYTEXT1) 
  and upper(CATEGORYTEXT2) like upper(:CATEGORYTEXT2) 
  and upper(CATEGORYTEXT3) like upper(:CATEGORYTEXT3) 
  and upper(DESCRIPTION) like upper(:DESCRIPTION)
  ORDER BY PRICE
dbLookupComboBox是:

dbLookupComboBox1: LCB_Manufacturers: OnSelect:  FilterProducts('MANUFACTURERNAME', LCB_Manufacturers.Text);
dbLookupComboBox2: LCB_Category1:     OnSelect:  FilterProducts('CATEGORYTEXT1', LCB_Category1.Text);
dbLookupComboBox3: LCB_Category2:     Onselect:  FilterProducts('CATEGORYTEXT2', LCB_Category2.Text);
dbLookupComboBox4: LCB_Category3:     OnSelect:  FilterProducts('CATEGORYTEXT3', LCB_Category3.Text);

ListSource is the DataSources for each FDQuery.
ListField and KeyField is respectively the MANUFACTURERNAME, CATEGORYTEXT1, CATEGORYTEXT2, CATEGORYTEXT3
  • 我使用“%”初始化所有参数
  • 我运行FDQuery1-4,现在所有制造商和类别都已填入组合中。
  • 我运行FDQuery5并在DBGrid中有一个未过滤的产品结果
  • 现在,我们已经准备好进行SQL筛选
  • 问题:
    DBLookupComboBox是否是此任务的正确组件选择

    这是处理这种过滤的正确方法吗

    我搞不懂FilterProducts的程序。我可以展示我的代码,但我认为这真的不好,过自己的生活

    很抱歉带来这么长的邮件。
    我在这方面花了很多时间,现在真的需要一个建议。

    我个人会在Delphi上进行本地筛选,而不是在数据库上。它在服务器上会更轻,而且可能更快(除非你真的有很多产品要过滤)

    您已经开始加载未筛选的FDQuery5以及所有可能的产品。现在,当用户选择过滤选项时,您可以直接在本地进行过滤,而不是运行新的SQL语句

    另外,我会更改您的FilterProducts,使每个选项都有不同的参数,以便用户可以选择多次选项

    可能是这样的:

    procedure MyForm.FilterProducts(ManufacturerName: string; CategoryText1: string; CategoryText2: string; CategoryText3: string);
    var Filter: string;
    begin
      Filter := 'MANUFACTURERNAME like ' + QuotedStr(ManufacturerName);
      Filter := Filter + ' and CATEGORYTEXT1 like ' + QuotedStr(CategoryText1);
      Filter := Filter + ' and CATEGORYTEXT2 like ' + QuotedStr(CategoryText2);
      Filter := Filter + ' and CATEGORYTEXT3 like ' + QuotedStr(CategoryText3);
    
      FDQuery5.FilterOptions := [foCaseInsensitive];
      FDQuery5.Filter := Filter;
      FDQuery5.Filtered := True;
    end;
    
    现在,所有组合框都可以调用相同的事件处理程序:

    dbLookupComboBox1: LCB_Manufacturers: OnSelect:  FilterProducts(LCB_Manufacturers.Text, LCB_Category1.Text, LCB_Category2.Text, LCB_Category3.Text);
    dbLookupComboBox2: LCB_Category1:     OnSelect:  FilterProducts(LCB_Manufacturers.Text, LCB_Category1.Text, LCB_Category2.Text, LCB_Category3.Text);
    dbLookupComboBox3: LCB_Category2:     Onselect:  FilterProducts(LCB_Manufacturers.Text, LCB_Category1.Text, LCB_Category2.Text, LCB_Category3.Text);
    dbLookupComboBox4: LCB_Category3:     OnSelect:  FilterProducts(LCB_Manufacturers.Text, LCB_Category1.Text, LCB_Category2.Text, LCB_Category3.Text);
    
    但是,如果您仍然希望运行新的SQL(因为FDQuery5上没有所有产品,只有前100个),那么将所有选择传递给FilterProduts后,在FDQuery5上检索所需的产品应该非常简单:

    procedure MyForm.FilterProducts(ManufacturerName: string; CategoryText1: string; CategoryText2: string; CategoryText3: string);
    begin
      FDQuery5.Close;
      FDQuery5.ParamsByName('MANUFACTURERNAME').Value := ManufacturerName;
      FDQuery5.ParamsByName('CATEGORYTEXT1').Value := CategoryText1;
      FDQuery5.ParamsByName('CATEGORYTEXT2').Value := CategoryText2;
      FDQuery5.ParamsByName('CATEGORYTEXT3').Value := CategoryText3;
      FDQuery5.Open;
    end;
    

    我有大约40000条记录,所以不能将它们全部加载到数据集中。本地过滤器也是如此。过滤产品工作得很好。非常感谢。但是如果你读了我的第一篇文章,我希望4个组合框根据其他组合框的选择更新为有效的选择。-我让它运行,但它杀死了我的大脑,因为我无法找出正确的代码。我选择了一个制造商和一个类别1+2。然后我决定改变第一类。轰,制造商组合现在是空的。我必须重新初始化。有什么诀窍吗?