我正在尝试过滤从数据库加载到 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;
不确定这是否是问题所在,但我在您的代码中看到的一个问题是,如果
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;
我在程序中使用了与此类似的构造,尽管我使用查询参数,而不是直接注入。为了防止OP的问题,查询的固定部分总是以'where 1 = 1'结尾,因此在此之后添加的任何额外子句都可以以'and ...'开头,而不必担心产生语法错误。