SQL在Delphi中过滤DBGrid

时间:2017-04-26 21:39:54

标签: sql delphi filtering firebird dbgrid

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

此外,我希望能够仅选择未选择制造商的Category1 + 2。

无论我从这4个Combos中选择什么,我都希望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' es:

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
  1. 我使用' %%'
  2. 初始化所有参数
  3. 我运行FDQuery1-4,现在所有制造商和类别都填入了Combos。
  4. 我运行FDQuery5并在DBGrid中有未经过滤的产品结果。
  5. 现在我们已准备好进行SQL过滤。
  6. 问题:
    dbLookupComboBox是否是此任务的正确选择组件?

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

    我无法找出FilterProducts过程。我可以展示我的代码,但我真的没有好处,过着自己的生活......

    很抱歉带来这么长的帖子。 我花了很多时间,现在真的需要建议。

1 个答案:

答案 0 :(得分:1)

我个人会在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上检索您想要的产品应该非常简单:< / p>

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;