【问题标题】:Postgres Check for Empty JSONB FieldsPostgres 检查空 JSONB 字段
【发布时间】:2017-11-16 20:42:42
【问题描述】:

如果在 Postgres 函数中有一个带有键但没有值的 JSON 对象,我希望能够ignore 或防止INSERT 发生。这是一个人为的小例子:

DROP TABLE IF EXISTS mytable;
create table mytable(
a text,
b text
);

CREATE OR REPLACE FUNCTION insert_to_table(
somedata JSONB
)
RETURNS VOID AS $$
BEGIN 
insert into mytable (a, b) select a,b from jsonb_populate_recordset(null::mytable, $1::jsonb);
END;
$$ LANGUAGE plpgsql;

select insert_to_table('[{"a":1,"b":2},{"a":3,"b":4}, {"a":null, "b": null}, {"a": null, "b": "some data"}]');

这将插入 4 条记录,第一行是 1,2,下一行是 3,4。第三行是"", "",第四行是"", some data

在这种情况下,第 1、2 和 4 行是有效的。我想忽略 3 并阻止它被插入。

我不想要一个空白行,我的数据/表格将比列出的要大得多(表格中大约有 20 个字段,JSON 中有 20 个键/值对)。

很可能我需要遍历数组并挑选出所有键均为空且不仅仅是 1 或 2 的 JSON 对象。

我该怎么做?

【问题讨论】:

    标签: sql json postgresql insert plpgsql


    【解决方案1】:

    在 Postgres 中,您可以使用查询中的表名(别名)来引用完整的行,并将其与 NULL 进行比较。如果 all 列为空,则记录被视为 NULL。所以你可以这样做:

    create or replace function insert_to_table(somedata jsonb)
    returns void as $$
    begin 
        insert into mytable (a, b) 
        select a, b 
        from jsonb_populate_recordset(null::mytable, somedata) as t
        where not (t is null);
    end;
    $$ language plpgsql;
    

    请注意,where t is not nullwhere not (t is null) 不同。无论列数或其数据类型如何,这都有效。

    将逻辑可视化。以下:

    select a,b,
           not (t is null) as "not (t is null)", 
           t is null as "t is null", 
           t is not null as "t is not null"
    from jsonb_populate_recordset(null::mytable, 
           '[{"a":1,"b":2},
             {"a":3,"b":4}, 
             {"a":null, "b": null}, 
             {"a": null, "b": "some data"}]'::jsonb) as t(a,b)
    

    返回:

    a | b         | not (t is null) | t is null | t is not null
    --+-----------+-----------------+-----------+--------------
    1 | 2         | true            | false     | true         
    3 | 4         | true            | false     | true         
      |           | false           | true      | false        
      | some data | true            | false     | false        
    

    无关的:

    演员$1::jsonb 没有用,因为您已经声明了该类型的参数。

    【讨论】:

    • 完美!感谢您的提示。注意 - 在第一个函数示例中 as 之后缺少 t
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-14
    • 2015-10-06
    • 1970-01-01
    • 2019-11-20
    相关资源
    最近更新 更多