如何防止在PostgreSQL的JSON列中插入“”或[](空字符串)作为值

问题描述 投票:0回答:3

我想防止在json列中插入“”或[](空字符串/数组)。请考虑以下示例: -

{"city":"LONDON","country":"UK","addressLine1":"PO Box 223456","postCode":"","addressLine2":"PO Box 47854"}

然后输出应删除“邮政编码”:“”并应显示如下: -

{"city":"LONDON","country":"UK","addressLine1":"PO Box 223456","addressLine2":"PO Box 47854"}

有人可以帮我这个吗?

json postgresql postgresql-9.3
3个回答
1
投票

您可以通过以下方式删除这些空值:

with my_table(json_col) as (
values (
'{
    "city": "LONDON",
    "country": "UK",
    "addressLine1": "PO Box 223456",
    "postCode": "",
    "addressLine2": "PO Box 47854",
    "array_to_delete": []
}'::jsonb)
)

select jsonb_object_agg(key, value)
from my_table
cross join lateral jsonb_each(json_col)
where value not in ('""', '[]');

                                           jsonb_object_agg                                           
------------------------------------------------------------------------------------------------------
 {"city": "LONDON", "country": "UK", "addressLine1": "PO Box 223456", "addressLine2": "PO Box 47854"}
(1 row) 

更新。在Postgres 9.3中:

with my_table(json_col) as (
values (
'{
    "city": "LONDON",
    "country": "UK",
    "addressLine1": "PO Box 223456",
    "postCode": "",
    "addressLine2": "PO Box 47854",
    "array_to_delete": []
}'::json)
)

select format('{%s}',string_agg(format('"%s": %s', key, to_json(value)), ','))::json
from my_table
cross join lateral json_each_text(json_col)
where value not in ('', '[]');

                                              format                                               
---------------------------------------------------------------------------------------------------
 {"city": "LONDON","country": "UK","addressLine1": "PO Box 223456","addressLine2": "PO Box 47854"}
(1 row)

更新。在这种情况下,无法应用检查约束,因为它只能接受或拒绝输入数据,而您想要修改它。您可以使用上述算法创建一个函数,并在触发器中使用它:

create or replace function filter_json_input()
returns trigger language plpgsql as $$
begin
    select format('{%s}', string_agg(format('"%s": %s', key, to_json(value)), ','))::json
    from json_each_text(new.json_col)
    where value not in ('', '[]')
    into new.json_col;
    return new;
end $$;

Full example in rextester.


0
投票

使用CTE,您可以使用以下查询执行此操作:

WITH j AS(
SELECT *
FROM json_each_text('{"city":"LONDON","country":"UK","addressLine1":"PO Box 223456","postCode":"","addressLine2":"PO Box 47854"}'::json)
WHERE value <> ''
) SELECT json_object_agg(j.key,j.value) FROM j

0
投票

我也使用PG 9.3。这是一个解决方案......也许太hacky了?但是它有效,我们经常手动构建JSON对象,因为它更快:P

SELECT ('{' || STRING_AGG('"' || key || '":' || TO_JSON(value), ',') || '}')::JSON
FROM json_each_text('{"city":"LONDON","country":"UK","addressLine1":"PO Box 223456","postCode":"","addressLine2":"PO Box 47854"}'::JSON)
WHERE COALESCE(value, '') <> ''

结果:{"city":"LONDON","country":"UK","addressLine1":"PO Box 223456","addressLine2":"PO Box 47854"}

© www.soinside.com 2019 - 2024. All rights reserved.