【问题标题】:Why jsonb-functions does not work on update when column is null?为什么当列为空时 jsonb-functions 对更新不起作用?
【发布时间】:2022-03-08 19:09:57
【问题描述】:

我有一个带有jsonb 列的表,其中列默认值为null。现在,当我第一次尝试使用jsonb_setjsonb_insert 使用数据更新此列时,我得到UPDATE 1,但实际上,该列保持null

我做了一个小测试用例:

CREATE SCHEMA test;
CREATE TABLE test.books (  
  book_id serial NOT NULL,
  data jsonb
);

INSERT INTO test.books (data) VALUES (null);
INSERT INTO test.books (data) VALUES ('{}');

现在我更新两条新记录:

UPDATE test.books SET data = jsonb_set( data, '{zzz}', 'true', true) WHERE book_id = 1;
UPDATE test.books SET data = jsonb_set( data, '{zzz}', 'true', true) WHERE book_id = 2;

结果:

# select * from test.books;
 book_id |                data                
---------+------------------------------------
       2 | {"zzz": true}
       1 | 
(2 rows)

即使更新对两次更新产生了相同的结果,第一行仍然保持不变。

我查看了文档,但没有发现任何有关此类行为的信息。为什么它不能这样工作?

我正在使用 Postgres 9.6

【问题讨论】:

标签: postgresql jsonb


【解决方案1】:

这是因为jsonb_set() 定义为strict,这意味着如果任何输入参数为null,则结果为空。

您需要在调用 jsonb_set 时使用 coalesce()

UPDATE books 
   SET data = jsonb_set( coalesce(data, '{}'), '{zzz}', 'true', true) 
WHERE book_id = 1;

请注意,函数的任何参数都是如此。
因此,即使data 不为空,jsonb_set(data, '{zzz}', null, true) 也会产生 null

【讨论】:

  • 很清楚,data 作为第一个参数是NULL。你从臀部拍摄这种情况;)
  • @w.k:我也偶然发现了这一点。但最终它的行为与例如相同。 some_text_column || 'add this' - 如果some_text_column 为空,则结果将为null
【解决方案2】:

在 JSONB 变量中设置原生 JSON 值 null 的方法如下:

IF condition = 1 THEN
    response = jsonb_set(
                    jsonb_in => response::jsonb,
                    path => ('{response, data, my_key')::text[],
                    replacement => 'null'::jsonb,
                    create_if_missing => true
                );
END IF;

【讨论】:

    猜你喜欢
    • 2011-09-04
    • 1970-01-01
    • 2019-03-17
    • 2020-09-30
    • 1970-01-01
    • 1970-01-01
    • 2021-06-18
    • 1970-01-01
    • 2011-03-15
    相关资源
    最近更新 更多