Where子句中的FireDac和参数失败

时间:2016-02-17 20:09:31

标签: delphi interbase firedac

我正在尝试使用Interbase中的可选参数进行相当简单的查询。我在德尔福10西雅图使用Firedac来称呼它。

SELECT STATUS_ID FROM TABLENAME
WHERE
  STATUS_ID=:STATUSID OR :STATUSID IS NULL

Dynamic SQL Error Code = -804 Unknown Datatype失败。

我只能隔离:STATUSID IS NULL部分,但它失败了。

仅使用STATUS_ID=:STATUSID将参数设置为null就可以正常工作,因此:STATUSID IS NULL部分会引发错误。

4 个答案:

答案 0 :(得分:1)

记得:

some_field = :some_param or :some_param is null

可以替换为

some_field = coalesce(:some_param, some_field)

另一种尝试的解决方案。

答案 1 :(得分:0)

我想出的答案是使用零作为我的“全部”条款。 哪里   STATUS_ID =:STATUSID OR:STATUSID = 0;

有效。 Null更好,因为它正确地要求No Entity,但似乎Firedac中的实现不支持它。

答案 2 :(得分:0)

我知道答案很晚。但我遇到了类似的问题。

我猜您的问题是因为您在STATUS_ID=:STATUSID之前测试:STATUSID IS NULL。也许它会与(:STATUSID IS NULL) OR (STATUS_ID=:STATUSID)

一起使用

对于数字字段,我想出了一个稍微不同的解决方案。对于整数PKeys,通常您的值永远不会为0.意味着您可以传递NULL或0,这仍然会返回所有行。 Lil更灵活。

SELECT * FROM WHATEVER
WHERE
((:ID IS NULL) OR (:ID <= 0) OR (:ID = ID))

对于字符串字段,可以是NULL或&#39;&#39; (空字符串)将返回所有行。

SELECT * FROM WHATEVER
WHERE
((:STR IS NULL) OR (TRIM(:STR) = CAST('' AS VARCHAR(10))) OR (:STR = CLIENT_NI))

你甚至可以把它们链起来像

SELECT * FROM WHATEVER
WHERE
((:ID IS NULL) OR (:ID <= 0) OR (:ID = ID)) AND 
((:STR IS NULL) OR (TRIM(:STR) = CAST('' AS VARCHAR(10))) OR (:STR = CLIENT_NI))

可能比为所有方案单独查询效率稍低,但如果您使用OK RDB,它会将参数WHERE子句优化为静态,并且您不会失败很多表现。我喜欢这个解决方案。

答案 3 :(得分:-2)

你可以使用演员

SELECT STATUS_ID 
FROM TABLENAME 
WHERE STATUS_ID=:STATUSID OR cast( :STATUSID as integer ) IS NULL

这适用于firebird,所以我猜它也适用于Interbase。