// 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(我希望它在其他数据库类型上也出错)。
有什么方法吗?
答案 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]);