我正在尝试使用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
部分会引发错误。
答案 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。