过滤 DBGrid 时不执行 SQL 查询

问题描述 投票:0回答:2

我正在尝试过滤从数据库加载到 DBGrid 中的产品。当我尝试过滤时,无法执行查询。它返回给我一个空白

sql.Text
。我不知道为什么会这样。

这是我的代码

procedure TProizvodiForm.PronadjiButtonClick(Sender: TObject);

var Filter: string;

begin
     Filter := 'SELECT productid as ID, name as Proizvod, code as Kod, manufname as Proizvodjac, unitname as Pakovanje FROM product WHERE ';

    if prizvodFilterTEdit.Text <> '' then
      begin

          Filter := Filter + '`name` LIKE ' + QuotedStr(prizvodFilterTEdit.Text+'%');

      end;
    if kodFilterTEdit.Text <> '' then
      begin
        Filter := Filter + ' AND code LIKE ' + QuotedStr(kodFilterTEdit.Text+'%');
      end;
    if proizvodjacFilterTEdit.Text <> '' then
      begin
        Filter := Filter + ' AND manufname LIKE ' + QuotedStr(proizvodjacFilterTEdit.Text+'%');
      end;

     with DB.ZQuerySelect do
      begin
        Active := false;
        sql.Clear;
        sql.Text := Filter;
        Active := true;

        ShowMessage(sql.Text); // debug
      end;
     
end;

但这可行 当我直接将查询放入

sql.Text
时,它可以工作,但是当设置为变量时,则不起作用。

with DB.ZQuerySelect do
      begin
        Active := false;
        sql.Clear;
        sql.Text := 'SELECT productid as ID, name as Proizvod, code as Kod, manufname as Proizvodjac, unitname as Pakovanje FROM product WHERE `name` LIKE ' + QuotedStr(prizvodFilterTEdit.Text+'%');
        Active := true;

        ShowMessage(sql.Text);
      end;
delphi dbgrid
2个回答
1
投票

不确定这是否是问题所在,但我在您的代码中看到的一个问题是,如果

prizvodFilterTEdit
控件为空,那么您的
Filter
字符串最终将成为 格式错误 SQL 语句(无论其他
TEdit
是什么) s),因为
WHERE
子句将为空,例如:

SELECT ... FROM product WHERE AND ...
                        ^^^^^^^^^

尝试使用该 SQL 时应该会出现运行时错误!

您没有足够准确地处理

WHERE
AND
子句,从而允许您省略过滤器子句(正如您的“工作”案例所做的那样)。 不要包含
WHERE
子句,除非您确实有要过滤的内容。 并且不要包含
AND
子句,除非过滤器中已存在较早的子句。

试试这个:

procedure TProizvodiForm.PronadjiButtonClick(Sender: TObject);
var
  SelectStmt, Filter: string;
begin
  SelectStmt := 'SELECT productid as ID, name as Proizvod, code as Kod, manufname as Proizvodjac, unitname as Pakovanje FROM product';

  if prizvodFilterTEdit.Text <> '' then
  begin
    Filter := '(`name` LIKE ' + QuotedStr(prizvodFilterTEdit.Text+'%') + ')';
  end;
  if kodFilterTEdit.Text <> '' then
  begin
    if Filter <> '' then
    begin
      Filter := Filter + ' AND ';
    end;
    Filter := Filter + '(code LIKE ' + QuotedStr(kodFilterTEdit.Text+'%') + ')';
  end;
  if proizvodjacFilterTEdit.Text <> '' then
  begin
    if Filter <> '' then
    begin
      Filter := Filter + ' AND ';
    end;
    Filter := Filter + '(manufname LIKE ' + QuotedStr(proizvodjacFilterTEdit.Text+'%') + ')';
  end;

  with DB.ZQuerySelect do
  begin
    Active := false;
    SQL.Clear;
    SQL.Add(SelectStmt);
    if Filter <> '' then
    begin
      SQL.Add('WHERE ' + Filter);
    end;
    Active := true;

    ShowMessage(SQL.Text); // debug
  end;
     
end;

0
投票

我在程序中使用了与此类似的构造,尽管我使用查询参数,而不是直接注入。为了防止OP的问题,查询的固定部分总是以'where 1 = 1'结尾,因此在此之后添加的任何额外子句都可以以'and ...'开头,而不必担心产生语法错误。

© www.soinside.com 2019 - 2024. All rights reserved.