SQL新手在这里我正在使用Grafana和Postgresql来构建一个可视化PoC,所以它非常粗糙,但我想自己学习和解决问题。我使用了一个自定义的filters
变量,它可以是空字符串。
我有一个CTE设置如下:
with filter1 as (
select json_array_elements_text(value) from json_each('${filters}') where key = 'filter1'
)
select case when '{$filters}' != '{}'
then sum(case when field in (select * from filter1) then 1 else 0 end)
-- then ... want to add multiple filters
else count(*)
end
from data;
所以过滤器可能是空的,这就是错误发生的时候。我希望CTE只在case
语句中被调用时才求值,但显然不是这样。
我已经注解掉了查询的不同部分,我知道当filters
变量为空时,错误出现在json_each
函数上。错误是pq: invalid input syntax for type json
。
我已经测试过了,所以当过滤器是空字符串时,值被解释为'{}'。
我尝试了json_each(coalesce('${filters}', '{}'::json))
,但似乎json_each
需要非空的json。
1条答案
按热度按时间z3yyvxxp1#
我尝试了json_each(coalesce('${filters}','{}'::json)),但似乎json_each需要非空的json。
除了CASE/CTE之外,这里还有两个问题。Coalesce希望所有的输入都是相同的类型,所以告诉它第二个是json将迫使第一个也是json,这只会调用您试图避免的错误。在聚结之后进行铸造,而不是在其内部:
但是如果
${filters}
是空字符串,这仍然不起作用,因为coalesce不认为空字符串与NULL相同。你可以用NULLIF解决这个问题。但是,一旦有了NULLIF,就不再需要合并,因为NULL是与json_each一起使用的法律的值,不像空字符串。
一旦你知道了解决问题的正确方法,你可能就可以在没有CTE的情况下做到这一点。
我没有测试这个确切的结构,因为
'${filters}'
不是PostgreSQL中处理参数的有效格式。这一定是客户端库把它修改成了正确的格式,所以我不得不伪造它,以便在psql中测试它。