DBGrid过滤时SQL Query无法执行,sql.Text为空问题求助
问题原因分析
你的代码在两种场景下会生成非法SQL语句,导致查询执行失败:
所有过滤输入框为空时:
拼接后的SQL会是:SELECT productid as ID, name as Proizvod, code as Kod, manufname as Proizvodjac, unitname as Pakovanje FROM product WHEREWHERE关键字后没有任何条件,数据库无法解析该语句,进而导致组件执行失败,sql.Text可能因错误被清空。第一个过滤框为空,但后续过滤框有值时:
比如仅kodFilterTEdit有输入,拼接后的SQL会是:SELECT productid as ID, name as Proizvod, code as Kod, manufname as Proizvodjac, unitname as Pakovanje FROM product WHERE AND code LIKE 'xxx%'WHERE后直接跟AND,属于语法错误,同样会导致查询执行失败。
而你直接赋值SQL的方式仅包含name的过滤条件,语句本身合法,所以能正常执行。
修复方案
通过单独收集过滤条件,再统一拼接的方式避免语法错误,以下是两种实现方式:
方式1:使用字符串变量收集条件
procedure TProizvodiForm.PronadjiButtonClick(Sender: TObject); var Filter, WhereClause: string; begin Filter := 'SELECT productid as ID, name as Proizvod, code as Kod, manufname as Proizvodjac, unitname as Pakovanje FROM product'; WhereClause := ''; // 收集name过滤条件 if prizvodFilterTEdit.Text <> '' then begin if WhereClause <> '' then WhereClause := WhereClause + ' AND '; WhereClause := WhereClause + '`name` LIKE ' + QuotedStr(prizvodFilterTEdit.Text + '%'); end; // 收集code过滤条件 if kodFilterTEdit.Text <> '' then begin if WhereClause <> '' then WhereClause := WhereClause + ' AND '; WhereClause := WhereClause + 'code LIKE ' + QuotedStr(kodFilterTEdit.Text + '%'); end; // 收集manufname过滤条件 if proizvodjacFilterTEdit.Text <> '' then begin if WhereClause <> '' then WhereClause := WhereClause + ' AND '; WhereClause := WhereClause + 'manufname LIKE ' + QuotedStr(proizvodjacFilterTEdit.Text + '%'); end; // 拼接WHERE子句(仅当有条件时) if WhereClause <> '' then Filter := Filter + ' WHERE ' + WhereClause; with DB.ZQuerySelect do begin Active := false; sql.Clear; sql.Text := Filter; Active := true; ShowMessage(sql.Text); // debug end; end;
方式2:使用TStringList收集条件
procedure TProizvodiForm.PronadjiButtonClick(Sender: TObject); var Filter: string; Conditions: TStringList; begin Filter := 'SELECT productid as ID, name as Proizvod, code as Kod, manufname as Proizvodjac, unitname as Pakovanje FROM product'; Conditions := TStringList.Create; try // 添加各过滤条件到列表 if prizvodFilterTEdit.Text <> '' then Conditions.Add('`name` LIKE ' + QuotedStr(prizvodFilterTEdit.Text + '%')); if kodFilterTEdit.Text <> '' then Conditions.Add('code LIKE ' + QuotedStr(kodFilterTEdit.Text + '%')); if proizvodjacFilterTEdit.Text <> '' then Conditions.Add('manufname LIKE ' + QuotedStr(proizvodjacFilterTEdit.Text + '%')); // 拼接条件(用AND连接) if Conditions.Count > 0 then Filter := Filter + ' WHERE ' + StringReplace(Conditions.Text, #13#10, ' AND ', [rfReplaceAll]); with DB.ZQuerySelect do begin Active := false; sql.Clear; sql.Text := Filter; Active := true; ShowMessage(sql.Text); // debug end; finally Conditions.Free; end; end;
这两种方式都会自动处理:
- 无过滤条件时,生成不带
WHERE的合法SQL - 多个条件时,自动用
AND连接,避免出现WHERE AND的语法错误
内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

