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

时间:2018-03-27 13:29:50

标签: json postgresql postgresql-9.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"}

有人可以帮我解决这个问题吗?

3 个答案:

答案 0 :(得分: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 $$;

enter image description here

答案 1 :(得分: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

答案 2 :(得分: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"}