在数据集过滤器中使用coalesce()

时间:2018-01-30 10:43:13

标签: delphi filter dataset delphi-10.2-tokyo

 // lItems is TDataSet or TClientDataSet
 with lItems do
 begin
   Close;
   Filtered := false;
   Filter := Format('coalesce(%s,0)=%d',[lFieldName,lInteger]);    // lInteger is >= 0, lFieldName is hard coded constant string representing a field name 
   Filtered := true;
   Open;

在使用

的开放语句(括号(coalesce(%s,0)=%d))上失败
  

未找到字段'coalesce'

这是Delphi Tokyo在FireBird数据库上使用FireDAC(我希望它在其他数据库类型上也出错)。

有什么方法吗?

3 个答案:

答案 0 :(得分:4)

就个人而言,我不希望Coalesce在TClientDataset过滤器中工作。基本上是一个服务器端例程,其中一些但并非所有Sql Server都支持。

TClientDataSet的表达式过滤器使用TExprParser(请参阅DBCommon.Pas)来支持其类似Sql的过滤器表达式,并查看其源代码(请参阅例程GetSQLToken)不支持{{1在D7(这是我在这台笔记本电脑上的全部内容),至少。此外,合并不属于Coalesce enumation中的项目,它有效地定义了TExprFilter和TClientDataSet支持的语法。

显而易见的解决办法是在用于检索CDS服务器数据的SQL表达式中包含对Coalesce的调用。

答案 1 :(得分:3)

FireDAC在其表达式引擎中支持 NVL IFNULL 函数(它们是等效的),但不支持 COALESCE 。 FireDAC的表达式引擎(在Filter属性后面使用)是独立于DBMS的,并且从内部存储本地执行过滤,因此这些函数适用于任何受支持的DBMS,即使它不支持它们也是如此。当FireDAC执行服务器端过滤时,特殊(实时)模式下的TFDTable filter有一个例外。

因此,而不是 COALESCE

Filter := Format('COALESCE(%s, 0) = %d', [lFieldName, lInteger]);

您可以使用 NVL IFNULL 编写过滤器,如下所示:

Filter := Format('NVL(%s, 0) = %d', [lFieldName, lInteger]);
Filter := Format('IFNULL(%s, 0) = %d', [lFieldName, lInteger]);

答案 2 :(得分:1)

案例陈述也将失败。您必须手动拆分0和> 0个案例:

if lInteger = 0 then
  Filter := Format('(%s is null) or (%s = 0)',[lFieldName,lFieldName])
else
  Filter := Format('(%s=%d)',[lFieldName,lInteger]);