在ADO数据集过滤器中使用LIKE和'%'

时间:2012-09-11 12:31:44

标签: delphi ado

尝试将过滤器应用于Delphi XE2中的ADO数据集时出现问题...

Filter := ' [Name] like ''%john'' ';

它引发了一个例外:

Project Test.exe raised exception class EOleException with message 
'Arguments are of the wrong type, are out of acceptable range, 
or are in conflict with one another'. Process stopped. 

但使用时:

Filter := ' [Name] like ''john%'' '

它工作正常!

为什么?

3 个答案:

答案 0 :(得分:3)

运营商只能是以下之一: =< > < => =<>喜欢 如果使用LIKE运算符,还可以使用*或%通配符作为字符串中的最后一个字符,或者作为字符串中的第一个和最后一个字符。

http://www.devguru.com/technologies/ado/quickref/recordset_filter.html

您可以在OnFilterRecord事件中捕获过滤器:

procedure TForm1.ADODataSet1FilterRecord(DataSet: TDataSet; var Accept: Boolean);
var
  iPos: Integer;
begin
  iPos:= pos('john',ADODataSet1name.AsString);
  if (iPos>0) and
     (iPos = length(ADODataSet1name.AsString)-3) then
  begin
    Accept:= True;
  end
  else
  begin
    Accept:= False;
  end;
end;

function TForm1.IsLastCriteria(AText: String): Boolean;
var
  iPos: Integer;
begin
  iPos:= pos(AText,ADODataSet1name.AsString);
  Result:= (iPos>0) and
           (iPos = length(ADODataSet1name.AsString)-length(AText)-1);
end;

procedure TForm1.ADODataSet1FilterRecord(DataSet: TDataSet; var Accept: Boolean);
begin
  Accept:= IsLastCriteria('john');
end;

答案 1 :(得分:2)

AS。我仍然请你阅读http://www.catb.org/esr/faqs/smart-questions.html#beprecise并相应地描述你的环境。

  • 什么是数据库服务器?
  • MDAC / ADO组件的版本是什么?
  • 查询是什么?
  • SQL中的名称列类型是什么?

你正在“提高”评论,这很好。但你不回答这些问题。这并不好。我们不是ESP人,我们会读你的想法。

我在上面的评论中给你一些建议。你试过吗?他们工作了吗?引用它们:

  1. 也许您可以将ADO / MDAC更新为2.8sp1版本。引用的MSDN知识库文章被告知适用于最高2.7版本的MDAC。也许2.8sp1不再有这种限制。
  2. 也许你可以使用一些特定于数据服务器的技巧,比如将姓名的最后4个字母复制到一个单独的列中。
  3. 也许您可以将该条件移动到SQL SELECT WHERE子句中并重新打开查询。
  4. 也许有像TBDEDataSet.OnFilterRecord
  5. 这样的事件处理程序

    有4种解决方法,您要么没有尝试过,要么没有报告结果。不太好。

    • 想法#1是不言自明的
    • @ SertacAkyuz详细说明了#3的想法,但缺乏有关您的计划的信息。
    • 想法#4由@ Ravaut123
    • 详细说明
    • 想法#2概述如下

    假设您的“ADO数据库”由Microsoft Access支持,并且根据http://www.databasedev.co.uk/access-sql-string-functions.html ... 或者使用MS SQL并根据http://msdn.microsoft.com/en-us/library/ms177532.aspx ... 还是......

    Query.SQL.Text:='选择右(姓名,4)为name_tail, *来自表格......'

    看到额外的列添加到查询中! 4是“约翰”的长度。

    使用类似的查询,以下过滤条件是等效的:

    • 过滤器:='[名称],如''%john''';
    • 过滤器:='[name_tail] =''john''';

    但是,如果某些行名称列短于4个字母,我不知道RIGHT函数会做什么。也许它会截断结果,或者可能抛出错误并中止查询。后者可能 - 取决于实际数据 - 可以通过填充空格到4长度来缓解,如

    LTrim(Right('    ' || Name, 4)) as name_tail
    

    这是供您测试的,因为只有您了解环境的详细信息。

答案 2 :(得分:2)

评论中提到了这个问题最简单的答案。 如果您使用星号而不是百分号,一切都会很好 过滤器:=' [姓名]喜欢'' * john'' &#39 ;;