简体   繁体   English

Postgres检查空的JSONB字段

[英]Postgres Check for Empty JSONB Fields

I want to be able to ignore or prevent an INSERT from occurring if there is a JSON object with keys but no values from within a Postgres function.Here is a small, contrived example: 我想能够ignore或阻止INSERT的发生,如果有一个具有键的JSON对象但Postgres函数中没有值,这是一个小的人为例子:

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"}]');

This will insert 4 records, with the first row being 1,2 and the next row being 3,4 . 这将插入4条记录,第一行为1,2 ,下一行为3,4 The third row is "", "" , and the forth is "", some data . 第三行是"", "" ,第四行是"", some data

In this scenario, rows 1,2, and 4 are valid. 在这种情况下,行1,2和4有效。 I want to ignore 3 and prevent it from being inserted. 我想忽略3并阻止其插入。

I do not want a blank row, and my data/table will be much larger than what is listed (roughly 20 fields in the table, and 20 key/value pairs in the JSON). 我不希望有空白行,并且我的数据/表将比列出的数据大得多(表中大约有20个字段,JSON中有20个键/值对)。

Most likely I will need to loop over the array and pick out JSON object where ALL the keys are null and not just 1 or 2. 我很可能需要遍历数组,并选择所有键均为null而不只是1或2的JSON对象。

How can I do that? 我怎样才能做到这一点?

In Postgres you can refer to a complete row using the name of the table (alias) in the query and compare that to NULL. 在Postgres中,您可以使用查询中的表名(别名)来引用完整的行,并将其与NULL比较。 A record is considered NULL if all columns are null. 如果所有列均为空,则记录被视为NULL。 So you can do: 因此,您可以执行以下操作:

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;

Note that where t is not null is something different then where not (t is null) . 请注意, where t is not null where not (t is null)不同where not (t is null)有所不同。 This works regardless of the number of columns or their data types. 无论列数或其数据类型如何,此方法均有效。

To visualize the logic. 可视化逻辑。 The following: 下列:

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)

returns: 收益:

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        

Unrelated: 无关:

The cast $1::jsonb is useless as you have declared the parameter of that type already. $1::jsonb无效,因为您已经声明了该类型的参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM