所以我有一个连接到数据库(mdb)的 AdoTable 和使用它的数据源。该数据源由 DBGrid 使用...
我尝试根据用户输入过滤 AdoTable。有 3 个重要的列:name、surname 和 ID。我想出了这样的临时解决方案:
AdoTable.filter:='surname like ' +
QuotedStr('%'+edit1.text+'%')+' or name like ' +
QuotedStr('%'+edit1.text+'%')+' or ID like ' +
QuotedStr('%'+edit1.text+'%');
AdoTable.filtered:=true;
它确实有效,但它并没有完全按照我想要的方式执行...(当搜索姓名和姓氏时,它不会找到任何内容,因为它只在一列中查找)。 所以后来我将代码修改为:
AdoTable.filter:='surname & " " & name like ' +
QuotedStr('%'+edit1.text+'%')+' or name & " " & surname like ' +
QuotedStr('%'+edit1.text+'%')+' or ID like ' +
QuotedStr('%'+edit1.text+'%');
AdoTable.filtered:=true;
现在这将完全按照我想要的方式进行,但它会引发异常(EOleException:参数类型错误,超出可接受的范围,或者相互冲突)。 这让我很惊讶,因为我认为它应该表现为 sql 命令中的 where 子句(并且它作为命令完美地工作)。
我尝试用“+”替换“&”。 我可以分割输入文本,但我不想这样做(如果你有 Robin van Persie、Ahmad ibn Hanbal 等名字,效果会很差..)
或者,我可以重写整个程序以使用查询而不是表,但我真的不想这样做(这也意味着每次用户更改 edit1.text 而不仅仅是过滤时我都会获得新的记录集)。
有什么想法吗?
编辑: 所以有效的命令看起来像这样
select * from person where surname & " " & name like '%John Smith%' or name & " " & surname like '%John Smith%' or ID like '%John Smith%'
过滤器看起来像这样(并且它触发异常)
surname & " " & name like '%John Smith%' or name & " " & surname like '%John Smith%' or ID like '%John Smith%'
请注意,可能有“hn Smith”而不是“John Smith”,因此它也会找到“Kahn Smithers”等。
最佳答案
下面的代码可以与 Access Delphi dbdemos.mdb
数据库中的 employee
表的 AdoTable 配合使用。我的 AdoConnection 使用 Microsoft Jet 4.0 OLE DB
驱动程序。
procedure TForm1.Button1Click(Sender: TObject);
var
FilterExpr : String;
begin
AdoTable1.Filtered := not AdoTable1.Filtered;
if AdoTable1.Filtered then begin
FilterExpr := 'FirstName like ' + QuotedStr('%' + Edit1.Text + '%') + ' or LastName like ' + QuotedStr('%' + Edit1.Text + '%');
AdoTable1.Filter := FilterExpr;
end;
end;
我认为您的错误可能是使用您提到的特定于 Access 的语法。您正在通过 ADO 层 Access 该表,并且 AFAIK 期望与您使用的语法相同,例如用于 Sql Server 后端。
从您的评论来看,您似乎想涵盖用户在 Edit1.Text 中输入名字片段,后跟空格,后跟片段或姓氏的情况。以下内容将做到这一点:
procedure TForm1.Button1Click(Sender: TObject);
var
FilterExpr : String;
P : Integer;
S1,
S2 : String;
begin
AdoTable1.Filtered := not AdoTable1.Filtered;
if AdoTable1.Filtered then begin
P := Pos(' ', Trim(Edit1.Text));
if P > 0 then begin
S1 := Copy(Trim(Edit1.Text), 1, P - 1);
S2 := Copy(Trim(Edit1.Text), P + 1, MaxInt);
FilterExpr := '(FirstName like ' + QuotedStr('%' + S1 + '%') + ')';
FilterExpr := FilterExpr + ' or (LastName like ' + QuotedStr('%' + S2 + '%') + ')';
end
else
FilterExpr := 'FirstName like ' + QuotedStr('%' + Edit1.Text + '%') + ' or LastName like ' + QuotedStr('%' + Edit1.Text + '%');
AdoTable1.Filter := FilterExpr;
end;
end;
更新:如果您想允许用户输入类似的内容
恩·史密斯
那么您可以使用像这样的 FilterRecord 事件来代替上面的代码。
procedure TForm1.ADOTable1FilterRecord(DataSet: TDataSet; var Accept: Boolean);
var
S : String;
begin
S := LowerCase(DataSet.FieldByName('FirstName').AsString + ' ' + DataSet.FieldByName('LastName').AsString);
Accept := Pos(LowerCase(Edit1.Text), S) > 0;
end;
显然,转换为小写字母是为了忽略用户可能使用的任何大写字母。
关于delphi - AdoDB 对合并列进行过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41931948/